
package com.gitee.l0km.aocache;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URL;
import java.nio.Buffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.TimeUnit;
import com.gitee.l0km.aocache.config.AoCacheGlobalConfig;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedMultiset;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.SortedMultiset;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
import com.google.common.collect.TreeMultiset;
import com.google.common.primitives.Primitives;
import com.google.common.reflect.TypeToken;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
 * 该类主要用于处理数据保护相关的功能，包括判断类是否为不可变类型、克隆对象、将对象转换为不可变对象等操作。
 * <p>
 * 它提供了一系列静态方法和常量，用于管理和操作已知的不可变类集合、接口类型到实例化类型的映射表等。
 * <br>
 * 具体功能包括：
 * <li>判断指定类是否为不可变类型，通过多种条件进行检查。</li>
 * <li>提供克隆对象的包装器，根据对象的特性选择合适的克隆方式。</li>
 * <li>提供将对象转换为不可变对象的包装器，根据对象的类型选择合适的转换方式。</li>
 * <li>管理各种缓存，避免重复计算和操作。</li>
 * </p>
 */
public class DataProtections{
	/**
	 * 已知的不可变类集合。<p>
	 */
	private static final Set<Class<?>> KNOWN_IMMUTABLE_CLASSES = ImmutableSet.<Class<?>>builder().add(
			String.class,
			URL.class,
			URI.class,
			File.class,
			Path.class,
			InetAddress.class,
			InetSocketAddress.class,
			UUID.class,
			BigInteger.class,
			BigDecimal.class
			).build();
	/** 
	 * 原始 Guava 包名前缀,guava库可能会被重定位，所以这里需要做兼容性处理。<br>
	 * 参见 com.gitee.l0km:aocachez 项目的pom.xml 中的shade插件。
	 */
	private static final String ORIGIN_GUAVA_PREFIX = "com_google".replace('_','.');
	/** 
	 * guava库被重定位后的包名前缀<br>
	 * 参见 com.gitee.l0km:aocachez 项目的pom.xml 中的shade插件。
	 */
	private static final String GUAVA_RELOCATED_PREFIX = "com.gitee.l0km.aocache.guava";
	/** guava库是否被重定位标志 */
	private static final boolean GUAVA_SHADED = !ORIGIN_GUAVA_PREFIX.equals("com.google");
	/**
	 * 原始 Guava 不可变类的前缀。<p>
	 * aocache依赖的guava库可能会被重定位，所以这里需要做兼容性处理。 
	 */
	private static final String ORIGIN_GUAVA_IMMUTABLE_PREFIX = "com_google_common_collect_Immutable".replace('_','.');
	/**
	 * 原始 Guava 不可变类的前缀。<p>
	 * aocache依赖的guava库可能会被重定位，所以这里需要做兼容性处理。 
	 */
	private static final String ORIGIN_GUAVA_OPTIONAL_PREFIX = "com_google_common_base_Optional".replace('_','.');
	/**
	 * 原始 Guava 不可变类的前缀。<p>
	 * aocache依赖的guava库可能会被重定位，所以这里需要做兼容性处理。 
	 */
	private static final String ORIGIN_GUAVA_TYPECAPTURE_PREFIX = "com_google_common_reflect_TypeCapture".replace('_','.');
	/**
	 * 原始 Guava 不可变类的前缀。<p>
	 * aocache依赖的guava库可能会被重定位，所以这里需要做兼容性处理。 
	 */
	private static final String ORIGIN_GUAVA_FLUENTITERABLE_PREFIX = "com_google_common_collect_FluentIterable".replace('_','.');

	/**
	 * 静态常量，存储表示@Immutable注解的类的全限定名。<p>
	 * 该常量用于在运行时检查类是否带有@Immutable注解。<br>
	 * 通过与类上的注解名称进行比较，可以确定类是否被标记为不可变。
	 */
	private static final String IMMUTABLE_ANNOT_CLASSNAME = "javax.annotation.concurrent.Immutable";
	/**
	 * 接口类型到实例化类型的映射表
	 */
	private static final Map<Class<?>, Class<?>> INSTANTIABLE_TYPES = createInstantiableTypes();
	
	private static final ConcurrentMap<Class<?>, Function<?, ?>> CLONE_FUN_CACHE = new MapMaker().weakValues().makeMap();
	private static final ConcurrentMap<List<?>, Function<?, ?>> DEEP_CLONE_FUN_CACHE = new MapMaker().weakValues().makeMap();
	private static final ConcurrentMap<Class<?>, Function<?,?>> IMMUTABLE_FUN_CACHE = new MapMaker().weakValues().makeMap();
	private static final ConcurrentMap<Class<?>, Boolean> CHECK_IMMUTABLE_CACHE = new MapMaker().weakValues().makeMap();
	private static final ConcurrentMap<TypeToken<?>, Boolean> CHECK_IMMUTABLE_TYPE_CACHE = new MapMaker().weakValues().makeMap();

    /**
     * 创建一个不可变的映射，将接口类型映射到可实例化的实现类类型。<p>
     * 该方法初始化一个映射，将常见的集合接口（如 Collection、Set、List 等）映射到它们的具体实现类。<br>
     * 同时，还处理了 Guava 库中的集合接口，确保在 Guava 库被重定位时也能正确映射。<p>
     * 最后，返回一个不可变的映射，确保映射关系不会被修改。
     *
     * @return 一个不可变的映射，包含接口类型到可实例化实现类类型的映射关系。
     */
    private static Map<Class<?>, Class<?>> createInstantiableTypes() {
		Map<Class<?>, Class<?>> map = new HashMap<>();
				map.put(Collection.class, ArrayList.class);
				map.put(Set.class, HashSet.class);
				map.put(List.class, ArrayList.class);
				map.put(Map.class, HashMap.class);
				map.put(Iterable.class, ArrayList.class);
				map.put(SortedSet.class, TreeSet.class);
				map.put(SortedMap.class, TreeMap.class);
				map.put(NavigableSet.class, TreeSet.class);
				map.put(NavigableMap.class, TreeMap.class);
				map.put(ConcurrentMap.class, ConcurrentHashMap.class);
				map.put(ConcurrentNavigableMap.class, ConcurrentSkipListMap.class);
		addGuavaInstantiableTypes(map, Multimap.class, LinkedListMultimap.class);
		addGuavaInstantiableTypes(map, ListMultimap.class, ArrayListMultimap.class);
		addGuavaInstantiableTypes(map, SetMultimap.class, LinkedHashMultimap.class);
		addGuavaInstantiableTypes(map, SortedSetMultimap.class, TreeMultimap.class);
		addGuavaInstantiableTypes(map, Multiset.class, LinkedHashMultiset.class);
		addGuavaInstantiableTypes(map, SortedMultiset.class, TreeMultiset.class);
		addGuavaInstantiableTypes(map, BiMap.class, HashBiMap.class);
		return Collections.unmodifiableMap(map);
	}
    /**
     * 向映射中添加 Guava 集合接口到可实例化实现类的映射关系。<p>
     * 该方法将指定的接口类型（key）映射到对应的可实例化实现类（value），并处理 Guava 库被重定位的情况。<br>
     * 如果接口类型被重定位，它会尝试找到原始的接口类型，并将其映射到原始的实现类类型。<p>
     * 具体步骤如下：<br>
     * <li>将接口类型（key）和对应的可实例化实现类（value）添加到映射中。</li>
     * <li>获取接口类型的原始类（如果被重定位）。</li>
     * <li>如果原始类与当前类不同，则将原始类映射到原始实现类。</li>
     *
     * @param map  要添加映射关系的映射对象
     * @param key  接口类型
     * @param value 可实例化的实现类类型
     */
    private static void addGuavaInstantiableTypes(Map<Class<?>, Class<?>> map,Class<?> key,Class<?> value) {
		map.put(key, value);
		if(GUAVA_SHADED) {
			map.put(originalClassOf(key), originalClassOf(value));
		}
	}

    /**
     * 获取指定类的原始类（处理Guava库重定位的情况）。<p>
     * 该方法会检查类的名称是否以重定位后的Guava包名前缀开头。<br>
     * 如果是，则尝试通过反射获取原始的类；如果不是，则直接返回该类。<p>
     * 具体步骤如下：<br>
     * <li>检查类的名称是否以重定位后的Guava包名前缀开头。</li>
     * <li>如果是，则将类名中的重定位前缀替换为原始的Guava包名前缀，并通过反射获取该类。</li>
     * <li>如果获取类时抛出ClassNotFoundException异常，则将其包装为RuntimeException抛出。</li>
     * <li>如果类名不以重定位后的Guava包名前缀开头，则直接返回该类。</li>
     *
     * @param clazz 要检查的类
     * @return 原始类，如果未重定位则返回原类
     * @throws RuntimeException 如果在获取原始类时抛出ClassNotFoundException异常
     */
    private static Class<?> originalClassOf(Class<?> clazz) {
		if(clazz.getName().startsWith(GUAVA_RELOCATED_PREFIX)){
			try {
				return Class.forName(clazz.getName().replace(GUAVA_RELOCATED_PREFIX, ORIGIN_GUAVA_PREFIX));
			} catch (ClassNotFoundException e) {
				throw new RuntimeException(e);
			}
		}
		return clazz;
	}
	/**
	 * 获取指定类在Guava库重定位后的类。<p>
	 * 该方法会检查类的名称是否以原始的Guava包名前缀开头。<br>
	 * 如果是，则尝试通过反射获取重定位后的类；如果不是，则直接返回该类。<p>
	 * 具体步骤如下：<br>
	 * <li>检查类的名称是否以原始的Guava包名前缀开头。</li>
	 * <li>如果是，则将类名中的原始前缀替换为重定位后的Guava包名前缀，并通过反射获取该类。</li>
	 * <li>如果获取类时抛出ClassNotFoundException异常，则将其包装为RuntimeException抛出。</li>
	 * <li>如果类名不以原始的Guava包名前缀开头，则直接返回该类。</li>
	 *
	 * @param clazz 要检查的类
	 * @return 重定位后的类，如果未重定位则返回原类
	 * @throws RuntimeException 如果在获取重定位后的类时抛出ClassNotFoundException异常
	 */
	private static Class<?> relocatedClassOf(Class<?> clazz) {
		if(GUAVA_SHADED && clazz.getName().startsWith(ORIGIN_GUAVA_PREFIX)){
			try {
				return Class.forName(clazz.getName().replace(ORIGIN_GUAVA_PREFIX, GUAVA_RELOCATED_PREFIX));
			} catch (ClassNotFoundException e) {
				throw new RuntimeException(e);
			}
		}
		return clazz;
	}
	@SuppressWarnings("rawtypes")
	private static final Function<List, List> IMMUTABLE_LIST_FUN = new AbstractWrapper<List>() {
		@SuppressWarnings("unchecked")
		@Override
		public List doApply(List input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return Collections.unmodifiableList(new ArrayList<>(input));
		}
	};
	@SuppressWarnings("rawtypes")
	private static final Function<Set, Set> IMMUTABLE_SET_FUN = new AbstractWrapper<Set>() {
		@SuppressWarnings("unchecked")
		@Override
		public Set doApply(Set input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return Collections.unmodifiableSet(new LinkedHashSet<>(input));
		}
	};
	@SuppressWarnings({"rawtypes","unchecked"})
	private static final Function<SortedSet, SortedSet> IMMUTABLE_SORTED_SET_FUN = new AbstractWrapper<SortedSet>() {
		@Override
		public SortedSet doApply(SortedSet input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return Collections.unmodifiableSortedSet(new TreeSet(input));
		}	
	};
	@SuppressWarnings("rawtypes")
	private static final Function<Map, Map> IMMUTABLE_MAP_FUN = new AbstractWrapper<Map>() {
		@SuppressWarnings("unchecked")
		@Override
		public Map doApply(Map input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return Collections.unmodifiableMap(new LinkedHashMap<>(input));
		}
	};

	@SuppressWarnings({"rawtypes","unchecked"})
	private static final Function<SortedMap, SortedMap> IMMUTABLE_SORTED_MAP_FUN = new AbstractWrapper<SortedMap>() {
		@Override
		public SortedMap doApply(SortedMap input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return Collections.unmodifiableSortedMap(new TreeMap(input));
		}
	};
	
	@SuppressWarnings("rawtypes")
	private static final Function<Multimap, Multimap> IMMUTABLE_MULTIMAP_FUN = new AbstractWrapper<Multimap>() {
		@SuppressWarnings("unchecked")
		@Override
		public Multimap doApply(Multimap input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return ImmutableMultimap.copyOf(input);
		}
	};
	@SuppressWarnings("rawtypes")
	private static final Function<ListMultimap, ListMultimap> IMMUTABLE_LIST_MULTIMAP_FUN = new AbstractWrapper<ListMultimap>() {
		@SuppressWarnings("unchecked")
		@Override
		public ListMultimap doApply(ListMultimap input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return ImmutableListMultimap.copyOf(input);
		}
	};
	@SuppressWarnings("rawtypes")
	private static final Function<Multiset, Multiset> IMMUTABLE_MULTISET_FUN = new AbstractWrapper<Multiset>() {
		@SuppressWarnings("unchecked")
		@Override
		public Multiset doApply(Multiset input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return ImmutableMultiset.copyOf(input);
		}
	};
	@SuppressWarnings("rawtypes")
	private static final Function<SetMultimap, SetMultimap> IMMUTABLE_SET_MULTIMAP_FUN = new AbstractWrapper<SetMultimap>() {
		@SuppressWarnings("unchecked")
		@Override
		public SetMultimap doApply(SetMultimap input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return ImmutableSetMultimap.copyOf(input);
		}
	};
	@SuppressWarnings("rawtypes")
	private static final Function<SortedMultiset, SortedMultiset> IMMUTABLE_SORTED_MULTISET_FUN = new AbstractWrapper<SortedMultiset>() {
		@SuppressWarnings("unchecked")
		@Override
		public SortedMultiset doApply(SortedMultiset input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return ImmutableSortedMultiset.copyOf(input);
		}
	};
	@SuppressWarnings("rawtypes")
	private static final Function<BiMap, BiMap> IMMUTABLE_BIMAP_FUN = new AbstractWrapper<BiMap>() {
		@SuppressWarnings("unchecked")
		@Override
		public BiMap doApply(BiMap input) {
			if (isImmutable(input.getClass())) {
				return input;
			}
			return ImmutableBiMap.copyOf(input);
		}
	};

	private static final Function<?, ?>  ARRAY_WRAPPER_FUN = new ArrayWrapper<>();
	private static final Function<?, ?>  SERIALIZABLE_WRAPPER_FUN = new SerializableWrapper<>();
	private static final Function<?,?>  DEEPCLONE_MISC_WRAPPER_FUN = new DeepCloneMiscWrapper<>();
    /**
     * 根据给定的类类型，返回一个用于克隆该类型对象的函数。<p>
     * 此方法会根据类的特性选择合适的克隆方式，如：<br>
     * <li>如果类是数组类型，使用数组克隆包装器。</li>
     * <li>如果类是不可变类型，直接返回原对象。</li>
     * <li>如果类实现了Cloneable接口，使用克隆包装器。</li>
     * <li>如果类有复制构造函数，使用复制构造包装器。</li>
     * <li>如果类有默认构造函数，且是Map、Multimap或Collection类型，使用相应的包装器。</li>
     * <li>如果类实现了Serializable接口，使用序列化包装器。</li>
     * <li>如果以上条件都不满足，直接返回原对象。</li>
     * 
     * @param <T> 要克隆的对象类型
     * @param clazz 要克隆的对象的类类型
     * @return 用于克隆该类型对象的函数
     */
	@SuppressWarnings({ "unchecked", "rawtypes" })
    private static <T> Function<T, T> cloneWrapperOf0(Class<T> clazz) {
		clazz = resolveSuperClassIfLocalOrAnonymous(clazz);
		if (clazz.isArray()) {
			return (Function<T, T>) ARRAY_WRAPPER_FUN;
		}
		if (isImmutable(clazz)) {
			/** 不可变类型不需要复制 */
			return Functions.identity();
		}
		Method cloneMethod = clonMethodOf(clazz);
		if (null != cloneMethod) {
			/** 允许通过clone方法创建对象 */
			return (Function<T, T>) new CloneableWrapper<>(cloneMethod);
		}
		if(Buffer.class != clazz && Buffer.class.isAssignableFrom(clazz)) {
			/** Buffer的子类 */
			return (Function<T, T>) new BufferWrapper((Class<? extends Buffer>)clazz, false);
		}
		Class<?> _clazz = instantiableClassOf(clazz);

		CreateCopyWrapper<T> createCopyWrapper = createCopyWrapperOf(_clazz, clazz);
		if (createCopyWrapper != null) {
			/** 允许通过createCopy方法创建对象 */
			return createCopyWrapper;
		}
		Constructor<?> copyCtor = getCopyConstructor(_clazz, clazz);
		if (copyCtor != null) {
			/** 允许通过复制构造函数创建对象 */
			return (Function<T, T>) new CopyConstructWrapper<>(copyCtor);
		}
		Constructor<?> defaultCtor = defaultConstructorOf(_clazz);
		if (null != defaultCtor) {
			/** 有默认构造函数的情况 */
			if (Map.class.equals(clazz)) {
				return (Function<T, T>) new MapWrapper(defaultCtor);
			}
			if (Collection.class.equals(clazz)) {
				return (Function<T, T>) new CollectionWrapper(defaultCtor);
			}
		}

		if (isJavaBean(clazz)) {
			return new JavaBeanWrapper(clazz, IdentityFilter.IDENTITY);
		}
		if (isSerializable(clazz)) {
			return (Function<T, T>) SERIALIZABLE_WRAPPER_FUN;
		}
		return Functions.identity();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static <T> Function<T, T> deepCloneWrapperOf0(TypeToken<T> type, IdentityFilter identityFilter) {
		type = resolveSuperTypeIfLocalOrAnonymous(type);

		if (identityFilter.identity(type)) {
			/** 不可变类型不需要复制 */
			return Functions.identity();
		}
		Class<?> typeClass = type.getRawType();
		Class<?> _clazz = instantiableClassOf(typeClass);
		if (isContainerType(type)) {
			if (type.isArray()) {
				return (Function<T, T>) new ArrayWrapper<>(type.getComponentType(), identityFilter);
			}
			if (type.isSubtypeOf(Collection.class)) {
				return (Function<T, T>) new CollectionCloneWrapper<Object, Collection<Object>>(_clazz,
						(TypeToken<Collection<Object>>) type, true, identityFilter);
			} else if (type.isSubtypeOf(Map.class)) {
				return (Function<T, T>) new MapCloneWrapper<Object, Object, T>(_clazz, 
						type, Map.class, identityFilter);
			} else if (type.isSubtypeOf(Multimap.class)) {
				return (Function<T, T>) new MapCloneWrapper<Object, Object, T>(_clazz,
						type, Multimap.class, identityFilter);
			} else if(GUAVA_SHADED && Multimap.class.isAssignableFrom(relocatedClassOf(type.getRawType()))) {
				return (Function<T, T>) new MapCloneWrapper<Object, Object, T>(_clazz,
						type, relocatedClassOf(Multimap.class), identityFilter);
			} 
		}
		if (isJavaBean(typeClass)) {
			return new JavaBeanWrapper(typeClass, identityFilter);
		}
		Method cloneMethod = clonMethodOf(typeClass);
		if (null != cloneMethod) {
			/** 允许通过clone方法创建对象 */
			return (Function<T, T>) new CloneableWrapper<>(cloneMethod);
		}
		if(Buffer.class != typeClass && Buffer.class.isAssignableFrom(typeClass)) {
			/** Buffer的子类 */
			return (Function<T, T>) new BufferWrapper((Class<? extends Buffer>)typeClass, true);
		}
		Constructor<?> copyCtor = getCopyConstructor(_clazz, typeClass);
		if (copyCtor != null) {
			/** 允许通过复制构造函数创建对象 */
			return (Function<T, T>) new CopyConstructWrapper<>(copyCtor);
		}
		if (isSerializable(typeClass)) {
			return (Function<T, T>) SERIALIZABLE_WRAPPER_FUN;
		}
		if (DeepCloneMiscWrapper.supported(_clazz)) {
			return (Function<T, T>) DEEPCLONE_MISC_WRAPPER_FUN;	
		}		
		return Functions.identity();
	}

	private static final Map<Class<?>, Function<?, ?>> IMMUTABLE_WRAPPERS = createImmutableWrappers();
	
	/**
     * 创建一个不可变的映射，将接口类型映射到用于将该类型对象转换为不可变对象的函数。<p>
     * 该方法初始化一个映射，将常见的集合接口（如 Map、Set、List 等）映射到对应的不可变包装器函数。<br>
     * 同时，还处理了 Guava 库中的集合接口，确保在 Guava 库被重定位时也能正确映射。<p>
     * 最后，返回一个不可变的映射，确保映射关系不会被修改。
     *
     * @return 一个不可变的映射，包含接口类型到用于将该类型对象转换为不可变对象的函数的映射关系。
     */
    private static final Map<Class<?>, Function<?,?>> createImmutableWrappers() {
		Map<Class<?>, Function<?,?>> map = new HashMap<>();
		map.put(Map.class, IMMUTABLE_MAP_FUN);
		map.put(SortedMap.class, IMMUTABLE_SORTED_MAP_FUN);
		map.put(Set.class, IMMUTABLE_SET_FUN);
		map.put(SortedSet.class, IMMUTABLE_SORTED_SET_FUN);
		map.put(List.class, IMMUTABLE_LIST_FUN);
		map.put(Collection.class, IMMUTABLE_LIST_FUN);
		map.put(Iterable.class, IMMUTABLE_LIST_FUN);
		addGuavaImmutableWrapper(map,ListMultimap.class, IMMUTABLE_LIST_MULTIMAP_FUN, ImmutableListMultimap.class);
		addGuavaImmutableWrapper(map,SortedMultiset.class, IMMUTABLE_SORTED_MULTISET_FUN, ImmutableSortedMultiset.class);
		addGuavaImmutableWrapper(map,Multiset.class, IMMUTABLE_MULTISET_FUN, ImmutableMultiset.class);
		addGuavaImmutableWrapper(map,SetMultimap.class, IMMUTABLE_SET_MULTIMAP_FUN, ImmutableSetMultimap.class);
		addGuavaImmutableWrapper(map,Multimap.class, IMMUTABLE_MULTIMAP_FUN, ImmutableMultimap.class);
		addGuavaImmutableWrapper(map,BiMap.class, IMMUTABLE_BIMAP_FUN, ImmutableBiMap.class);
		return Collections.unmodifiableMap(map);
	}

    /**
     * 向映射中添加Guava集合接口到将该类型对象转换为不可变对象的函数的映射关系。<p>
     * 该方法将指定的接口类型（key）映射到对应的将该类型对象转换为不可变对象的函数（value），并处理Guava库被重定位的情况。<br>
     * 如果接口类型被重定位，它会尝试找到原始的接口类型，并将其映射到一个通过指定的不可变类创建副本的包装器函数。<p>
     * 具体步骤如下：<br>
     * <li>将接口类型（key）和对应的将该类型对象转换为不可变对象的函数（value）添加到映射中。</li>
     * <li>如果Guava库被重定位（GUAVA_SHADED为true），则查找不可变类中用于创建副本的静态方法，并创建一个CreateCopyWrapper实例。</li>
     * <li>将原始的接口类型映射到该CreateCopyWrapper实例。</li>
     *
     * @param map 要添加映射关系的映射对象
     * @param key 接口类型
     * @param value 用于将该类型对象转换为不可变对象的函数
     * @param immutabClass 不可变类，用于查找创建副本的静态方法
     */
    private static void addGuavaImmutableWrapper(Map<Class<?>, Function<?, ?>> map, Class<?> key, Function<?, ?> value,
			Class<?> immutabClass) {
		map.put(key, value);
		if (GUAVA_SHADED) {
			Class<?> originalKey = originalClassOf(key);
			Class<?> originalImmutableClass = originalClassOf(immutabClass);
			CreateCopyWrapper<?> createCopyWrapper = createCopyWrapperOf(originalImmutableClass, originalKey);
			checkNotNull(createCopyWrapper, "CAN NOT FIND create copy Method for %s in %s", originalKey, originalImmutableClass);
			map.put(originalKey, createCopyWrapper);
		}
	}
	/**
	 * 根据给定的类类型，返回一个用于将该类型对象转换为不可变对象的函数。<p>
	 * 此方法会根据类的特性选择合适的转换方式，如：<br>
	 * <li>如果类是不可变类型，直接返回原对象。</li>
	 * <li>如果类在预定义的不可变包装器映射中，使用相应的包装器进行转换。</li>
	 * <li>如果以上条件都不满足，直接返回原对象。</li>
	 * 
	 * @param <T> 要转换的对象类型
	 * @param clazz 要转换的对象的类类型
	 * @return 用于将该类型对象转换为不可变对象的函数
	 */
	@SuppressWarnings("unchecked")
    private static <T> Function<T, T> immutableWrapperOf0(Class<T> clazz) {
		if (isImmutable(clazz)) {
			/** 不可变类型不需要复制 */
			return Functions.identity();
		}
		Function<T, T> fun = (Function<T, T>) IMMUTABLE_WRAPPERS.get(clazz);
		if (fun != null) {
			return fun;
		}
		return Functions.identity();
	}

	/**
     * 根据给定的类类型，返回一个用于克隆该类型对象的函数。<p>
     * 此方法会先从缓存中查找是否已经有该类对应的克隆函数，若有则直接返回；若没有，则调用
     * {@link #cloneWrapperOf0(Class)} 方法生成一个新的克隆函数，并将其存入缓存。<br>
     * 具体克隆逻辑由 {@link #cloneWrapperOf0(Class)} 方法实现，该方法会根据类的特性选择合适的克隆方式，如：<br>
     * <li>如果类是数组类型，使用数组克隆包装器。</li>
     * <li>如果类是不可变类型，直接返回原对象。</li>
     * <li>如果类实现了Cloneable接口，使用克隆包装器。</li>
     * <li>如果类有复制构造函数，使用复制构造包装器。</li>
     * <li>如果类有默认构造函数，且是Map、Multimap或Collection类型，使用相应的包装器。</li>
     * <li>如果类实现了Serializable接口，使用序列化包装器。</li>
     * <li>如果以上条件都不满足，直接返回原对象。</li>
     * 
     * @param <T> 要克隆的对象类型
     * @param clazz 要克隆的对象的类类型
     * @return 用于克隆该类型对象的函数
     * @see #cloneWrapperOf0(Class)
     */
	@SuppressWarnings("unchecked")
    public static <T> Function<T, T> cloneWrapperOf(Class<T> clazz) {
		Function<T, T> fun = (Function<T, T>) CLONE_FUN_CACHE.get(checkNotNull(clazz, "clazz can not be null"));
		if (fun == null) {
			fun = cloneWrapperOf0(clazz);
			CLONE_FUN_CACHE.putIfAbsent(clazz, fun);

		}
		return fun;
	}
	@SuppressWarnings("unchecked")
	static <T> Function<T, T> deepCloneWrapperOf(TypeToken<T> typeToken, IdentityFilter identityFilter) {
		List<?> args = Arrays.asList(checkNotNull(typeToken, "typeToken can not be null"),
				checkNotNull(identityFilter, "identityFilter can not be null"));
		Function<?, ?> fun = DEEP_CLONE_FUN_CACHE.get(args);
		if (fun == null) {
			fun = deepCloneWrapperOf0(typeToken, identityFilter);
			DEEP_CLONE_FUN_CACHE.putIfAbsent(args, fun);

		}
		return (Function<T, T>) fun;
	}

	@SuppressWarnings("unchecked")
	public static <T> Function<T, T> deepCloneWrapperOf(Type type, IdentityFilter identityFilter) {
		return (Function<T, T>) deepCloneWrapperOf(TypeToken.of(checkNotNull(type, "type can not be null")),
				checkNotNull(identityFilter, "identityFilter can not be null"));
	}
	
	/**
	 * 根据给定的类型令牌，返回一个用于深度克隆该类型对象的函数。<p>
	 * 此方法会先从缓存中查找是否已经有该类型对应的深度克隆函数，若有则直接返回；<br>
	 * 若没有，则调用 {@link #deepCloneWrapperOf0(TypeToken)} 方法生成一个新的深度克隆函数，并将其存入缓存。<p>
	 * 具体深度克隆逻辑由 {@link #deepCloneWrapperOf0(TypeToken)} 方法实现，该方法会根据类型的特性选择合适的克隆方式，如：<br>
	 * <li>如果类型是基本数据类型，直接返回原对象。</li>
	 * <li>如果类型是容器类型（如数组、集合、映射等），会递归克隆其元素。</li>
	 * <li>如果类型是JavaBean，会通过反射调用其getter和setter方法进行克隆。</li>
	 * <li>如果类型实现了Cloneable接口，使用克隆包装器。</li>
	 * <li>如果类型有复制构造函数，使用复制构造包装器。</li>
	 * <li>如果类型实现了Serializable接口，使用序列化包装器。</li>
	 * <li>如果以上条件都不满足，直接返回原对象。</li>
	 * 
	 * @param <T> 要深度克隆的对象类型
	 * @param typeToken 要深度克隆的对象的类型令牌
	 * @return 用于深度克隆该类型对象的函数
	 * @see #deepCloneWrapperOf0(TypeToken)
	 */
	static <T> Function<T, T> deepCloneWrapperOf(TypeToken<T> typeToken) {
		return deepCloneWrapperOf(typeToken,IdentityFilter.PRIMITIVE);
	}
	public static <T> Function<T, T> deepCloneWrapperOf(Type type) {
		return deepCloneWrapperOf(type, IdentityFilter.PRIMITIVE);
	}
    /**
     * 根据给定的类类型，返回一个用于将该类型对象转换为不可变对象的函数。<p>
     * 此方法会先从缓存中查找是否已经有该类对应的转换函数，若有则直接返回；若没有，则调用
     * {@link #immutableWrapperOf0(Class)} 方法生成一个新的转换函数，并将其存入缓存。<br>
     * 具体转换逻辑由 {@link #immutableWrapperOf0(Class)} 方法实现，该方法会根据类的特性选择合适的转换方式，如：<br>
     * <li>如果类是不可变类型，直接返回原对象。</li>
     * <li>如果类在预定义的不可变包装器映射中，使用相应的包装器进行转换。</li>
     * <li>如果以上条件都不满足，直接返回原对象。</li>
     * 
     * @param <T> 要转换的对象类型
     * @param clazz 要转换的对象的类类型
     * @return 用于将该类型对象转换为不可变对象的函数
     * @see #immutableWrapperOf0(Class)
     */
    @SuppressWarnings("unchecked")
    public static <T> Function<T, T> immutableWrapperOf(Class<T> clazz){
		Function<T, T> fun = (Function<T, T>) IMMUTABLE_FUN_CACHE.get(checkNotNull(clazz, "clazz can not be null"));
		if (fun == null) {
			fun = immutableWrapperOf0(clazz);
			IMMUTABLE_FUN_CACHE.putIfAbsent(clazz, fun);
		}
		return fun;
	}
    private static Class<?> instantiableClassOf(Class<?> clazz) {
		Class<?> instantiable = INSTANTIABLE_TYPES.get(clazz);
		return instantiable == null ? clazz : instantiable;
	}

    /**
     * 解析局部类或匿名类的泛型超类型。<p>
     * 该方法用于处理局部类或匿名类，尝试获取其泛型超类型。<br>
     * 具体逻辑如下：<br>
     * <li>若传入的类是局部类或匿名类，首先检查其泛型超类。如果泛型超类是{@link ParameterizedType} 或 {@link Class} 类型，则返回该泛型超类。</li>
     * <li>若泛型超类不满足条件，接着检查其实现的泛型接口。如果第一个泛型接口是{@link ParameterizedType} 类型，则返回该泛型接口。</li>
     * <li>若传入的类不是局部类或匿名类，直接返回该类。</li>
     * 
     * @param clazz 要检查的类
     * @return 若类是局部类或匿名类，返回其泛型超类型；否则返回原类
     */
	static Type resolveSuperTypeIfLocalOrAnonymous(Class<?> clazz) {
		if (clazz.isAnonymousClass() || clazz.isLocalClass()) {
			Type genericSuperclass = clazz.getGenericSuperclass();
			// 检查泛型超类
			if (genericSuperclass != null && Object.class != genericSuperclass) {
				return genericSuperclass;
			}
			// 检查实现的泛型接口
			Type[] genericInterfaces = clazz.getGenericInterfaces();
			if (genericInterfaces.length > 0) {
				return genericInterfaces[0];
			}
		}
		return clazz;
	}

	/**
	 * 解析局部类或匿名类的泛型超类型令牌。
	 * <p>
	 * 该方法用于处理局部类或匿名类对应的类型令牌，尝试获取其泛型超类型令牌。<br>
	 * 具体逻辑如下：<br>
	 * <li>若类型令牌对应的原始类是局部类或匿名类，首先检查其泛型超类。如果泛型超类是{@link ParameterizedType} 或
	 * {@link Class} 类型，则返回基于该泛型超类的类型令牌。</li>
	 * <li>若泛型超类不满足条件，接着检查其实现的泛型接口。如果第一个泛型接口是{@link ParameterizedType}
	 * 类型，则返回基于该泛型接口的类型令牌。</li>
	 * <li>若类型令牌对应的原始类不是局部类或匿名类，直接返回原类型令牌。</li>
	 * 
	 * @param <T>       类型令牌所代表的类型
	 * @param typeToken 要检查的类型令牌
	 * @return 若类型令牌对应的原始类是局部类或匿名类，返回其泛型超类型令牌；否则返回原类型令牌
	 */
	@SuppressWarnings("unchecked")
	private static <T> TypeToken<T> resolveSuperTypeIfLocalOrAnonymous(TypeToken<T> typeToken) {
		Type resolvedType = resolveSuperTypeIfLocalOrAnonymous(typeToken.getRawType());
		if (TypeToken.of(resolvedType).getRawType() == typeToken.getRawType()) {
			return typeToken;
		}
		return (TypeToken<T>) TypeToken.of(resolvedType);
	}

	/**
	 * 解析局部类或匿名类的超类。
	 * <p>
	 * 该方法用于处理局部类或匿名类，尝试获取其超类或实现的第一个接口。<br>
	 * 具体逻辑如下：<br>
	 * <li>若传入的类是局部类或匿名类，首先检查其超类。如果超类存在且不是Object类，则返回该超类。</li>
	 * <li>若超类不满足条件，接着检查其实现的接口。如果存在实现的接口，则返回第一个接口。</li>
	 * <li>若传入的类不是局部类或匿名类，直接返回该类。</li>
	 * 
	 * @param clazz 要检查的类
	 * @return 若类是局部类或匿名类，返回其超类或第一个接口；否则返回原类
	 */
	@SuppressWarnings("unchecked")
	static <T> Class<T> resolveSuperClassIfLocalOrAnonymous(Class<T> clazz) {
		if (clazz.isAnonymousClass() || clazz.isLocalClass()) {
			Class<?> superclass = clazz.getSuperclass();
			// 检查超类
			if (superclass != null && Object.class != superclass) {
				return (Class<T>) superclass;
			}

			// 检查实现的接口
			Class<?>[] interfaces = clazz.getInterfaces();
			if (interfaces.length > 0) {
				return (Class<T>) interfaces[0];
			}
		}
		return clazz;
	}

	/**
	 * 检查指定类是否带有@Immutable注解。
	 * <p>
	 * 该方法会遍历指定类的所有注解，检查是否存在全限定名为 "javax.annotation.concurrent.Immutable" 的注解。<br>
	 * 如果找到该注解，则认为该类带有@Immutable注解，返回true；<br>
	 * 如果未找到，则返回false。
	 *
	 * @param clazz 要检查的类
	 * @return 如果类带有@Immutable注解则返回true，否则返回false
	 */
	private static boolean checkImmutableAnnotation(Class<?> clazz) {
		for (Annotation annotation : clazz.getAnnotations()) {
			if (annotation.annotationType().getName().equals(IMMUTABLE_ANNOT_CLASSNAME)) {
				return true;
			}
		}
		return false;
	}

    /**
     * 检查指定类的所有非静态字段是否都是final的。<p>
     * 该方法会递归检查类及其所有父类的非静态字段。<br>
     * 如果类是接口，则直接返回false，因为接口中的字段默认是静态常量。<br>
     * 若类的所有非静态字段都是final的，且这些字段的类型也是不可变的，则返回true；否则返回false。
     *
     * @param clazz 要检查的类
     * @return 如果类的所有非静态字段都是final的，则返回true；否则返回false
     */
    private static boolean checkAllFinal(Class<?> clazz) {
        // 若类为接口，直接返回false，因为接口中字段默认是静态常量
        if(clazz.isInterface()) {
            return false;
        }
        // 递归检查所有字段是否为final（包括父类）
        // 初始化当前检查的类为传入的类
        Class<?> currentClass = clazz;
        // 循环条件：当前类不为空且不是Object类
		while (currentClass != null && currentClass != Object.class) {
			// 遍历当前类的所有声明字段,跳过合成字段
			for (Field field : currentClass.getDeclaredFields()) {
				if(field.isSynthetic()){
					continue;
				}
				// 获取字段的修饰符
				int modifiers = field.getModifiers();
				// 若字段不是静态且不是final，说明存在非静态非final字段，返回false
				if (!Modifier.isStatic(modifiers)) {
					if (!Modifier.isFinal(modifiers) || !isImmutable(field.getType())) {
						return false;
					}
				}
			}
			// 向上检查父类
			currentClass = currentClass.getSuperclass();
		}
        // 若所有非静态字段都是final且为不可变类型，返回true
        return true;
    }

    /**
     * 判断指定的类是否为不可变类型。<p>
     * 该方法会检查以下几种情况来确定类是否为不可变类型：<br>
     * 0. 如果类是数组类型（通过clazz.isArray()判断），则直接返回false<br>
     * 1. 如果类是基本数据类型（通过 Primitives.unwrap 转换后），则认为是不可变的。<br>
     * 2. 如果类属于java.lang.reflect包，则认为是不可变的。<br>
     * 3. 如果类带有 @Immutable 注解，则认为是不可变的。<br>
     * 4. 如果类的所有非静态字段都是 final 的，则认为是不可变的。<br>
     * 5. 如果类在已知的不可变类集合中，则认为是不可变的。<br>
	 * 6. 如果类的名称以 "java.util.Collections$Unmodifiable" 开头，则认为是不可变的。<br>
	 * 7. 如果类的名称以 "java.util.Collections$Singleton" 开头，则认为是不可变的。<br>
	 * 8. 如果类的名称以 "java.util.Collections$Empty" 开头，则认为是不可变的。<br>
	 * 9. 如果类的名称以 "java.util.Collections$CopiesList" 开头，则认为是不可变的。<br>
	 * 10. 如果类的名称以 "java.util.Arrays$ArrayList" 开头，则认为是不可变的。<br>
	 * 11. 如果类是Guava库中的不可变类（通过 isGuavaImmutableClass 方法判断），则认为是不可变的。<br>
	 * 12. 如果类是JavaBean（通过 isJavaBean 方法判断），则认为是可变的。<br>
     * <p>
     * 如果以上条件都不满足，则认为该类不是不可变类型。
     *
     * @param clazz 要检查的类
     * @return 如果类是不可变类型则返回 true，否则返回 false
     */
    private static boolean isImmutable0(Class<?> clazz){
    	if(clazz.isArray()) {
    		return false;
    	}
    	/** 作为类型，根类Object不是不可变的 */
        if(clazz == Object.class) {
        	return false;
        }
		/** 基本数据类型和包装类都是不可变的 */
		if(Primitives.unwrap(clazz).isPrimitive()){
			return true;
		}
		if(Enum.class.isAssignableFrom(clazz)) {
			return true;
		}
		if(Annotation.class.isAssignableFrom(clazz)){
			return true;
		}
		if (clazz.getPackage() != null && clazz.getPackage().getName().equals("java.lang.reflect")) {
			return true;
		}
		if (checkImmutableAnnotation(clazz)) {
			return true;
		}
		if (checkAllFinal(clazz)) {
			return true;
		}
		if (KNOWN_IMMUTABLE_CLASSES.contains(clazz)) {
			return true;
		}
		
		if(clazz.getName().startsWith("java.util.Collections$Unmodifiable")){
            return true;
        }
		if(clazz.getName().startsWith("java.util.Collections$Singleton")){
			return true;
		}
		if(clazz.getName().startsWith("java.util.Collections$Empty")){
			return true;
		}
		if(clazz.getName().startsWith("java.util.Collections$CopiesList")){
			return true;
		}
		if(clazz.getName().startsWith("java.util.Arrays$ArrayList")){
			return true;
		}
		if(isGuavaImmutableClass(clazz)){
			return true;
		}
		if(isJavaBean(clazz)){
			return false;
		}
		return false;
	}
    /**
     * 判断指定的类是否为Guava库中的不可变类。<p>
     * 该方法会检查以下几种情况来确定类是否为Guava库中的不可变类：<br>
     * <li>如果类是接口，则直接返回false。</li>
     * <li>如果类名以 "com.google.common.collect.Immutable" 开头，则认为是不可变的。</li>
     * <li>如果类名以 "com.google.common.base.Optional" 开头，则认为是不可变的。</li>
     * <li>如果Guava库被重定位（GUAVA_SHADED为true），且类名以预先定义的Guava不可变类前缀开头，则认为是不可变的。</li>
     * <li>如果Guava库被重定位（GUAVA_SHADED为true），且类名以预先定义的Guava可选类前缀开头，则认为是不可变的。</li>
     * <li>如果类名以 "com.google" 开头，会进一步检查其父类或封闭类是否为Guava不可变类。</li>
     * <li>如果Guava库被重定位（GUAVA_SHADED为true），且类名以预先定义的Guava包名前缀开头，会进一步检查其父类或封闭类是否为Guava不可变类。</li>
     * <p>
     * 如果以上条件都不满足，则认为该类不是Guava库中的不可变类。
     *
     * @param clazz 要检查的类
     * @return 如果类是Guava库中的不可变类则返回true，否则返回false
     */
    private static boolean isGuavaImmutableClass(Class<?> clazz) {
		if(clazz.isInterface()) {
			return false;
		}
		if(clazz.getName().startsWith("com.google.common.collect.Immutable")){
			return true;
		}
		if(clazz.getName().startsWith("com.google.common.base.Optional")){
			return true;
		}
		/** TypeCapture视为不可变类，即包括了其所有子类:TypeToken,TypeParameter */
		if(clazz.getName().startsWith("com.google.common.reflect.TypeCapture")){
			return true;
		}
		if(clazz.getName().startsWith("com.google.common.collect.FluentIterable")){
			return true;
		}
		if(GUAVA_SHADED && clazz.getName().startsWith(ORIGIN_GUAVA_IMMUTABLE_PREFIX)){
			return true;
		}
		if(GUAVA_SHADED && clazz.getName().startsWith(ORIGIN_GUAVA_OPTIONAL_PREFIX)){
			return true;
		}
		if(GUAVA_SHADED && clazz.getName().startsWith(ORIGIN_GUAVA_TYPECAPTURE_PREFIX)){
			return true;
		}
		if(GUAVA_SHADED && clazz.getName().startsWith(ORIGIN_GUAVA_FLUENTITERABLE_PREFIX)){
			return true;
		}
		/** 
		 * 检查父类是否为guava的不可变类，
		 * 如:
		 * TypeParameter 是抽象类，应用场景一般是匿名子类，
		 * TypeToken 是抽象类, 也有匿名子类的应用 
		 */
		for (Class<?> currentClass = clazz.getSuperclass(); null != currentClass
				&& currentClass != Object.class; currentClass = currentClass.getSuperclass()) {
			if (isGuavaImmutableClass(currentClass)) {
				return true;
			}
		}		
		if(Modifier.isStatic(clazz.getModifiers()) && clazz.isMemberClass()){
			return isGuavaImmutableClass(clazz.getEnclosingClass());
		}
		return false;
	}

	/**
     * 判断指定的类是否为不可变类型，使用缓存机制以提高性能。<p>
     * 该方法会先从缓存中查找指定类是否为不可变类型的结果。<br>
     * 如果缓存中存在结果，则直接返回该结果；<br>
     * 如果缓存中不存在结果，则调用 {@link #isImmutable0(Class)} 方法进行判断，并将结果存入缓存中。<br>
     * <p>
     * 此方法的具体判断逻辑依赖于 {@link #isImmutable0(Class)} 方法，该方法会检查多种情况来确定类是否为不可变类型。<br>
     * 例如，基本数据类型、带有 @Immutable 注解的类、所有非静态字段都是 final 的类等都被认为是不可变类型。<br>
     * <p>
     * 使用缓存机制可以避免对同一类的重复判断，提高性能。
     *
     * @param clazz 要检查的类
     * @return 如果类是不可变类型则返回 true，否则返回 false
     * @see #isImmutable0(Class)
     */
    public static boolean isImmutable(Class<?> clazz){
    	clazz = resolveSuperClassIfLocalOrAnonymous(clazz);
		Boolean result = CHECK_IMMUTABLE_CACHE.get(clazz);
		if(result == null) {
			result = isImmutable0(clazz);
			CHECK_IMMUTABLE_CACHE.putIfAbsent(clazz, result);
		}
		return result;
	}
    /** @see #isImmutable(Class) */
    public static boolean isImmutable(Object input) {
    	return null == input ? true : isImmutable(input.getClass());
    }
    /**
     * 判断指定的类是否为可实例化的类。<p>
     * 该方法会检查类是否为非接口、非抽象类，并且如果是成员类，它必须是静态的。<br>
     * 具体来说，会获取类的修饰符，然后检查类是否不是接口，不是抽象类，并且要么是静态类，要么不是成员类。<br>
     * 如果满足这些条件，则认为该类是可实例化的，返回 true；否则返回 false。
     *
     * @param clazz 要检查的类
     * @return 如果类是可实例化的则返回 true，否则返回 false
     */
	private static boolean isInstantiableClass(Class<?> clazz) {
		int modifiers = clazz.getModifiers();
		return !clazz.isInterface() && !Modifier.isAbstract(modifiers)
				&& (Modifier.isStatic(modifiers) || !clazz.isMemberClass());
	}

    /**
     * 获取指定类的克隆方法。<p>
     * 该方法会检查指定类是否实现了 Cloneable 接口。<br>
     * 如果实现了 Cloneable 接口，则尝试获取该类的 "clone" 方法。<br>
     * 如果获取方法时抛出 NoSuchMethodException 或 SecurityException 异常，则忽略该异常并返回 null。<br>
     * 如果类未实现 Cloneable 接口，也返回 null。
     *
     * @param clazz 要检查的类
     * @return 类的克隆方法，如果未找到则返回 null
     */
    private static Method clonMethodOf(Class<?> clazz){
        if(Cloneable.class.isAssignableFrom(clazz)){
            try{
                return clazz.getMethod("clone");
            }catch (NoSuchMethodException | SecurityException e) {
                // DO NOTHING
            }
        }
        return null;
    }

    /**
     * 判断指定的类是否实现了 Serializable 接口，并且是静态类或非成员类。<p>
     * 该方法会检查类是否可赋值给 Serializable 接口，并且调用 isStaticOrNonMemberClass 方法检查类是否为静态类或非成员类。<br>
     * 如果类实现了 Serializable 接口，并且是静态类或非成员类，则认为该类是可序列化的，返回 true；<br>
     * 否则返回 false。
     *
     * @param clazz 要检查的类
     * @return 如果类实现了 Serializable 接口且是静态类或非成员类则返回 true，否则返回 false
     */
    private static boolean isSerializable(Class<?> clazz) {
		return isInstantiableClass(clazz) && Serializable.class.isAssignableFrom(clazz);
	}
    private static boolean hasReadWriteMethod(Class<?> clazz, Field field) {
		String fieldName = field.getName();
		String prefix = field.getType() == boolean.class ? "is" : "get";
		String getter = prefix + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
		String setter = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);

		try {
			Method getterMethod = clazz.getMethod(getter);
			Method setterMethod = clazz.getMethod(setter, field.getType());

			if (!Modifier.isPublic(getterMethod.getModifiers()) || 
				!Modifier.isPublic(setterMethod.getModifiers()) ||
				Modifier.isStatic(getterMethod.getModifiers()) ||
				Modifier.isStatic(setterMethod.getModifiers())) {
				return false;
			}else {
				return true;
			}
		} catch (NoSuchMethodException e) {
			return false;
		}
    }
    /**
     * 判断指定的类是否符合 JavaBean 规范。<p>
     * 该方法会检查类是否满足以下 JavaBean 规范的要求：<br>
     * <li>类必须是可实例化的（非接口、非抽象类，且如果是成员类，必须是静态的）。</li>
     * <li>类必须是公共类。</li>
     * <li>类必须有一个公共的无参构造器。</li>
     * <li>类必须至少有一个非静态、非 final、非公共的字段。</li>
     * <li>类的每个非静态、非 final、非公共的字段都必须有对应的公共的 getter 和 setter 方法。</li>
     * <p>
     * 如果类满足以上所有条件，则认为该类符合 JavaBean 规范，返回 <code>true</code>；<br>
     * 否则返回 <code>false</code>。
     *
     * @param clazz 要检查的类
     * @return 如果类符合 JavaBean 规范则返回 <code>true</code>，否则返回 <code>false</code>
     */
	static boolean isJavaBean(Class<?> clazz) {
		if (!isInstantiableClass(clazz)) {
			return false;
		}
		// 检查是否为公共类
		if (!Modifier.isPublic(clazz.getModifiers())) {
			return false;
		}

		// 检查公共无参构造器
		try {
			clazz.getConstructor();
		} catch (NoSuchMethodException e) {
			return false;
		}
		Map<String, Field> fields = collectNonStaticFields(clazz);
		if (fields.isEmpty()) {
			return false;
		}
		/**
		 * 检查字段的getter/setter方法，
		 * 如果是非public方法必须有对应的getter/setter方法，否则返回false
		 */ 
		for (Field field : fields.values()) {
			if (!Modifier.isPublic(field.getModifiers()) && !hasReadWriteMethod(clazz, field)) {
				return false;
			}
		}
		return true;
	}
    static final ThrowingFunctionCached<Class<?>, Map<String, Field>> NON_STATIC_FIELDS_CACHE =
		ThrowingFunctionCached.builder()
		.weakValues().maximumSize(200).expireAfterAccess(60, TimeUnit.SECONDS)
		.getterFunction(new ThrowingFunction<Class<?>, Map<String, Field>, Throwable>() {
			@Override
			public Map<String, Field> apply(Class<?> input) {
				return collectNonStaticFields0(input);
			}
		}).build();

	/**
	 * 收集指定类及其所有父类的非静态字段，并将它们存储在一个不可变的映射中。<p>
	 * 该方法会遍历指定类及其所有父类的声明字段，排除合成字段、静态字段和 final 字段。<br>
	 * 如果遇到 final 字段，将直接返回一个空的不可变映射。<p>
	 * 最终返回的映射以字段名作为键，字段对象作为值，并且是不可变的，确保映射内容不会被修改。<p>
	 * 
	 * @param clazz 要收集非静态字段的类
	 * @return 一个不可变的映射，包含指定类及其所有父类的非静态字段，键为字段名，值为字段对象；如果遇到 final 字段，返回空映射
	 */
	private static Map<String, Field> collectNonStaticFields0(Class<?> clazz) {
		LinkedHashMap<String, Field> fields = new LinkedHashMap<>();
		for(Class<?> _class = clazz; _class != Object.class; _class = _class.getSuperclass()){
			for(Field field : _class.getDeclaredFields()){
				if(field.isSynthetic()) {
					continue;
				}
				if (Modifier.isStatic(field.getModifiers())) {
					continue;
				}
				if(Modifier.isFinal(field.getModifiers())) {
					return Collections.emptyMap();
				}
				if(fields.containsKey(field.getName())) {
					continue;
				}
				fields.put(field.getName(), field);
			}
		}
		return Collections.unmodifiableMap(fields);
	}
	private static Map<String, Field> collectNonStaticFields(Class<?> clazz) {
		try {
			return NON_STATIC_FIELDS_CACHE.get(clazz);
		} catch (Throwable e) {
			Throwables.throwIfUnchecked(e);
			throw new RuntimeException(e);
		}
	}

	/**
     * 获取指定类中以指定参数类型为参数的构造函数。<p>
     * 该方法会检查类是否为可实例化的类（非接口、非抽象类，且如果是成员类，必须是静态的）。<br>
     * 如果类是可实例化的，会检查参数类是否为类的父类或接口，如果不是则抛出IllegalArgumentException异常。<br>
     * 若参数类为null，则将其设置为类本身。<br>
     * 最后，使用AocacheUtils工具类查找匹配的可访问构造函数。<br>
     * 如果类不可实例化，则返回null。
     *
     * @param clazz 要查找构造函数的类
     * @param parameClass 构造函数参数的类
     * @return 匹配的构造函数，如果未找到则返回null
     * @throws IllegalArgumentException 如果parameClass不是clazz的父类或接口
     */
    private static Constructor<?> getCopyConstructor(Class<?> clazz, Class<?> parameClass) {
		if (isInstantiableClass(clazz)) {
			if (null == parameClass) {
				parameClass = clazz;
			}
			checkArgument(parameClass.isAssignableFrom(clazz), "parameClass must be assignable from clazz");
			return AocacheUtils.getAccessibleConstructor(clazz, new Class[] { parameClass });
		}
		return null;
	}

    /**
     * 获取指定类中用于创建副本的静态方法。<p>
     * 该方法会遍历类的所有公共方法，查找符合以下条件的方法：<br>
     * <li>方法是公共的（public）。</li>
     * <li>方法是静态的（static）。</li>
     * <li>方法有一个参数，且该参数类型与parameClass相同。</li>
     * <li>方法的返回类型与类的类型相同。</li>
     * <p>
     * 如果parameClass为null，则将其设置为clazz。<br>
     * 如果parameClass不是clazz的父类或接口，则抛出IllegalArgumentException异常。<br>
     * 如果找到符合条件的方法，则返回该方法；如果未找到，则返回null。
     *
     * @param clazz 要查找方法的类
     * @param parameClass 方法参数的类
     * @return 符合条件的方法，如果未找到则返回null
     * @throws IllegalArgumentException 如果parameClass不是clazz的父类或接口
     */
	private static Method getCreateCopyMethod(final Class<?> clazz, Class<?> parameClass) {
		if (null == parameClass) {
			parameClass = clazz;
		}
		checkArgument(parameClass.isAssignableFrom(clazz), "parameClass must be assignable from clazz");
		for (Method m : clazz.getMethods()) {
			Class<?>[] parameterTypes = m.getParameterTypes();
			if (Modifier.isStatic(m.getModifiers()) 
					&& parameterTypes.length == 1
					&& parameterTypes[0].isAssignableFrom(parameClass) 
					&& m.getReturnType().equals(clazz)) {
				return m;
			}
		}
		return null;
	}
    /**
     * 创建一个用于通过静态方法创建对象副本的包装器。<p>
     * 该方法会查找指定类中用于创建副本的静态方法。<br>
     * 如果找到符合条件的方法，则创建一个CreateCopyWrapper实例来调用该方法。<br>
     * 符合条件的方法需要满足以下条件：<br>
     * <li>方法是公共的（public）。</li>
     * <li>方法是静态的（static）。</li>
     * <li>方法有一个参数，且该参数类型与parameClass相同。</li>
     * <li>方法的返回类型与类的类型相同。</li>
     * <p>
     * 如果parameClass为null，则将其设置为clazz。<br>
     * 如果parameClass不是clazz的父类或接口，则抛出IllegalArgumentException异常。<br>
     * 如果未找到符合条件的方法，则返回null。
     *
     * @param clazz 要查找方法的类
     * @param parameClass 方法参数的类
     * @return 一个CreateCopyWrapper实例，用于调用创建副本的静态方法；如果未找到方法，则返回null
     * @throws IllegalArgumentException 如果parameClass不是clazz的父类或接口
     */
    private static <T> CreateCopyWrapper<T> createCopyWrapperOf(Class<?> clazz, Class<T> parameClass) {
		Method createCopyMethod = getCreateCopyMethod(clazz, parameClass);
		if (null == createCopyMethod) {
			return null;
		}
		return new CreateCopyWrapper<>(createCopyMethod);
	}
    /**
     * 判断指定的类是否具有默认构造函数。<p>
     * 该方法会检查类是否为非抽象类，并且是静态成员类（如果是成员类的话）。<br>
     * 然后尝试查找类中是否存在一个无参数的构造函数。<br>
     * 如果找到这样的构造函数，则认为该类具有默认构造函数，返回 true；<br>
     * 如果未找到，或者在查找过程中抛出异常，则返回 false。<br>
     * <p>
     * 对于查找构造函数时可能抛出的异常，该方法会在内部处理。
     *
     * @param clazz 要检查的类
     * @return 如果类具有默认构造函数则返回 true，否则返回 false
     */
    private static Constructor<?> defaultConstructorOf(Class<?> clazz){
    	if(isInstantiableClass(clazz)) {
    		try{
    			return clazz.getConstructor();
    		}catch (NoSuchMethodException | SecurityException e) {
    			// DO NOTHING
    		}
    	}
        return null;
    }
    private static ImmutableSet<Class<?>> EXCLUDE_CONTAINER_TYPES = ImmutableSet.<Class<?>>builder()
    		.add(Path.class).build();

	/**
	 * 判断指定的输入对象及其类型是否为不可变类型。<p>
	 * 该方法会根据输入对象和传入的类型令牌，检查对象是否为不可变类型。<br>
	 * 具体步骤如下：
	 * <li>若输入对象为 null，则直接返回 true。</li>
	 * <li>检查输入类型是否为输入对象的超类型，若不满足则抛出 IllegalArgumentException 异常。</li>
	 * <li>若输入对象的类为 Object.class，则作为实例类型视为不可变，返回 true。</li>
	 * <li>若输入类型为 null 或其原始类为 Object.class，则调用 {@link #isImmutable(Class)} 方法检查输入对象的类是否为不可变类。</li>
	 * <li>否则，调用 {@link #isImmutable(TypeToken)} 方法检查输入类型是否为不可变类型。</li>
	 * </p>
	 * 
	 * @param <T> 输入对象的类型
	 * @param input 要检查的输入对象
	 * @param inputType 输入对象的类型令牌，用于指定检查的目标类型
	 * @return 如果输入对象及其类型为不可变类型则返回 <code>true</code>，否则返回 <code>false</code>
	 * @throws IllegalArgumentException 如果输入类型不是输入对象的超类型
	 */
	@SuppressWarnings("unchecked")
	static <T> boolean isImmutable(T input, TypeToken<T> inputType) {
		if (null == input) {
			return true;
		}
		Class<?> rawType;
		/** inputType为null或Object,对input的类型没有约束，要用input的实际类型来检查 */
		if (null == inputType) {
			rawType = input.getClass();
			inputType = (TypeToken<T>) TypeToken.of(input.getClass());
		} else if ((rawType = inputType.getRawType()) == Object.class) {
			inputType = (TypeToken<T>) TypeToken.of(input.getClass());
		} else {
			checkArgument(Primitives.wrap(rawType).isAssignableFrom(input.getClass()),
					"inputType %s is not supertype of input %s", inputType, input.getClass());
		}
		/** 作为实例的类型，Object.class 是不可变的 */
		if (input.getClass() == Object.class) {
			return true;
		}
		/** 目标类型为null或Object,对input的类型没有约束，要用input的实际类型来检查 */
		if (rawType == Object.class) {
			return isImmutable(input.getClass());
		}
		return isImmutable(inputType);
	}
	@SuppressWarnings("unchecked")
	static <T> boolean isImmutable(T input, Type inputType) {
		return isImmutable(input, null == inputType ? null : (TypeToken<T>)TypeToken.of(inputType));
	}
	/**
	 * @see #isImmutable(Object, TypeToken)
	 */
	static boolean isImmutable(Type type) {
		return isImmutable(TypeToken.of(type));
	}

    /**
     * 判断指定的 {@link TypeToken} 所代表的类型是否为不可变类型。<p>
     * 该方法会检查多种情况来确定类型是否为不可变类型：<br>
     * <li>首先检查类型的原始类是否为不可变类，若不是则直接返回 false。</li>
     * <li>若类型为容器类型（如集合、映射等），会递归检查其类型参数是否为不可变类型。</li>
     * <li>若以上检查都通过，则认为该类型是不可变类型，返回 true。</li>
     * </p>
     * 
     * @param token 要检查的类型令牌
     * @return 如果类型是不可变类型则返回 <code>true</code>，否则返回 <code>false</code>
     */
    private static boolean isImmutable0(TypeToken<?> token) {
		if (!isImmutable0(token.getRawType())) {
			return false;
		}
		if (isContainerType(token)) {
			Type[] typeArguments = getTypeArguments(token, false);
			for (Type type : typeArguments) {
				if (!isImmutable0(TypeToken.of(type))) {
					return false;
				}
			}
		}
		return true;
	}
	/**
	 * 判断指定的 {@link TypeToken} 所代表的类型是否为不可变类型，使用缓存机制以提高性能。<p>
	 * 该方法会先从缓存中查找指定类型是否为不可变类型的结果。<br>
	 * 如果缓存中存在结果，则直接返回该结果；<br>
	 * 如果缓存中不存在结果，则调用 {@link #isImmutable0(TypeToken)} 方法进行判断，并将结果存入缓存中。<p>
	 * 此方法的具体判断逻辑依赖于 {@link #isImmutable0(TypeToken)} 方法，该方法会检查多种情况来确定类型是否为不可变类型。<br>
	 * 例如，会检查类型的原始类是否为不可变类，若类型为容器类型，还会递归检查其类型参数是否为不可变类型。<p>
	 * 使用缓存机制可以避免对同一类型的重复判断，提高性能。
	 * 
	 * @param token 要检查的类型令牌
	 * @return 如果类型是不可变类型则返回 <code>true</code>，否则返回 <code>false</code>
	 * @see #isImmutable0(TypeToken)
	 */
	static boolean isImmutable(TypeToken<?> token) {
		Boolean result = CHECK_IMMUTABLE_TYPE_CACHE.get(token);
		if(result == null) {
			result = isImmutable0(token);
			CHECK_IMMUTABLE_TYPE_CACHE.putIfAbsent(token, result);
		}
		return result;
	}
	/**
	 * 返回 {@code containerType}的类型参数数组，
	 * 如果{@code containerType}不是{@link Class}或{@link ParameterizedType}则抛出 {@link IllegalArgumentException}
	 * @param containerType
	 * @param superType {@code containerType}的超类或实现的接口
	 * @return 类型参数数组
	 */
	private static Type[] getTypeArguments(TypeToken<?> containerType, Class<?> superType) {
		if(containerType.getType() instanceof ParameterizedType) {
			ParameterizedType parameterizedType = (ParameterizedType) containerType.getType();
			return parameterizedType.getActualTypeArguments();
		}else if(containerType.getType() instanceof Class) {
			TypeVariable<?>[] typevars = containerType.getRawType().getTypeParameters();
			Type[] superTypevars;
			if (typevars.length == 0 && (superTypevars = superType.getTypeParameters()).length!=0) {
				/** 
				 * Class.getTypeParameters() 返回的是声明的类型参数，
				 * 没有返回类型参数的情况下，使用 TypeToken.resolveType方法解析 superType的参数变量获取元素类型
				 * 比如 java.nio.Path 实现了 Iterable<Path>,但是没有返回类型参数，
				 * 所以需要使用 TypeToken.resolveType方法解析 Path的参数变量获取元素类型,
				 * 类似的例子还有 java.util.Properties 实现了 Map<Object,Object>,但是没有返回类型参数。
				 */
				Type[] resolvedTypes = new Type[superTypevars.length];
				for (int i = 0; i < superTypevars.length; i++) {
					resolvedTypes[i] = containerType.resolveType(superTypevars[i]).getType();
				}
				return resolvedTypes;
			}else {
				return typevars;
			}
		}
		throw new IllegalArgumentException("unsupported type: " + containerType.getType());
	}
	/**
	 * 获取指定类型令牌的类型参数数组。<p>
	 * 根据类型令牌的不同类型，调用 {@link #getTypeArguments(TypeToken, Class)} 方法获取类型参数。<br>
	 * 支持的类型包括 {@link Iterable}、{@link Map}、{@link Multimap} 和数组类型。<p>
	 * 如果类型不支持且 <code>throwfUnsupported</code> 为 <code>true</code>，则抛出 {@link UnsupportedOperationException} 异常。<p>
	 * 如果类型不支持且 <code>throwfUnsupported</code> 为 <code>false</code>，则返回 {@link AocacheConstant#EMPTY_TYPE_ARRAY}。
	 * 
	 * @param token 要获取类型参数的类型令牌。
	 * @param throwfUnsupported 当类型不支持时是否抛出异常的标志。
	 * @return 类型参数数组，如果类型不支持且 <code>throwfUnsupported</code> 为 <code>false</code>，则返回空数组。
	 */
	private static Type[] getTypeArguments(TypeToken<?> token, boolean throwfUnsupported) {
		if (token.isSubtypeOf(Iterable.class)) {
			/** Iterable类型的元素类型为唯一的类型参数 */
			return getTypeArguments(token, Iterable.class);
		} else if (token.isSubtypeOf(Map.class)) {
			return getTypeArguments(token, Map.class);
		} else if (token.isSubtypeOf(Multimap.class)) {
			return getTypeArguments(token, Multimap.class);
		} else if (token.isArray()) {
			/** 数组类型的元素类型为数组元素类型 */
			return new Type[] { token.getComponentType().getType() };
		}
		if (throwfUnsupported) {
			throw new UnsupportedOperationException("unsupported container type: " + token);
		}
		return AocacheConstant.EMPTY_TYPE_ARRAY;
	}
	/**
	 * 判断 {@code type} 是否实现了容器类型(Map,Iterable,Multimap,Multiset)接口，但不是容器类型<br>
	 * 有的类型虽然实现了容器类型(Map,Iterable,Multimap,Multiset)接口，但是实际上并不是容器类型，
	 * 比如Path，实现了Iterable接口，但是并不是容器类型。
	 * 此时需要排除掉这些类型，避免转换错误。
	 * @param type
	 * @return 如果是容器类型则返回 {@code true}，否则返回 {@code false}
	 */
	protected static boolean isFakeContainerType(Class<?> type){
		if(EXCLUDE_CONTAINER_TYPES.contains(type)){
			return true;
		}
		for(Class<?> excludeType : EXCLUDE_CONTAINER_TYPES){
			if(excludeType.isAssignableFrom(type)){
				return true;
			}
		}
		return false;
	}
	protected static boolean isContainerType(Class<?> clazz) {
		if (isFakeContainerType(clazz)) {
			return false;
		}
		boolean isContainer= Map.class.isAssignableFrom(clazz) || Iterable.class.isAssignableFrom(clazz)
				|| Multimap.class.isAssignableFrom(clazz) || Multiset.class.isAssignableFrom(clazz)
				|| clazz.isArray();
		if(isContainer) {
			return true;
		}
		Class<?> relocatedClass = relocatedClassOf(clazz);
		if(relocatedClass != clazz){
			return isContainerType(relocatedClass);
		}
		return false;
	}
	protected static boolean isContainerType(TypeToken<?> type) {
		return isContainerType(type.getRawType());
	}
	static boolean isContainerType(Type type){
		return isContainerType(TypeToken.of(type));
	}

	/**
	 * 对输入对象进行深度克隆操作。<p>
	 * 该方法会根据输入对象的类型和传入的类型令牌，对对象进行深度克隆。<br>
	 * 具体步骤如下：
	 * <li>若输入对象为 null，则直接返回 null。</li>
	 * <li>若传入的类型令牌为 null 或其原始类为 Object.class，则将输入对象的实际类作为类型令牌。</li>
	 * <li>若输入对象为 Object 类的实例，会创建一个新的 Object 实例并返回。</li>
	 * <li>若输入对象及其类型为不可变类型，则直接返回输入对象。</li>
	 * <li>否则，调用相应的深度克隆包装器函数对输入对象进行深度克隆。</li>
	 * </p>
	 * 
	 * @param <T> 输入对象的类型
	 * @param input 要进行深度克隆的输入对象
	 * @param inputType 输入对象的类型令牌，用于指定克隆操作的目标类型
	 * @param identityFilter 用于过滤不可变类型的过滤器
	 * @return 输入对象的深度克隆副本，如果输入对象为 null，则返回 null
	 */
	@SuppressWarnings("unchecked")
	static <T> T deepClone(T input, TypeToken<T> inputType, IdentityFilter identityFilter) {
		if (null == input) {
			return null;
		}
		Class<?> rawType;
		/** inputType为null或Object,对input的类型没有约束，要用input的实际类型来检查 */
		if (null == inputType) {
			rawType = input.getClass();
			inputType = (TypeToken<T>) TypeToken.of(input.getClass());
		}else if((rawType = inputType.getRawType()) == Object.class){
			inputType = (TypeToken<T>) TypeToken.of(input.getClass());	
		}
		/** NOTE: 输入为Object对象的深度克隆操作，直接返回一个新对象 */
		if (input.getClass() == Object.class) {
			checkArgument(rawType == Object.class,
					"inputType must be Object.class if input is Object instance");
			return (T) new Object();
		}
		if (identityFilter.identity(inputType)) {
			/** 不可变类型不需要复制 */
			return input;
		}
		return (T) deepCloneWrapperOf(inputType, identityFilter).apply(input);
	}
	/**
	 * @see #deepClone(T, TypeToken, IdentityFilter)
	 */
	@SuppressWarnings("unchecked")
	static <T> T deepClone(T input, Type inputType, IdentityFilter identityFilter){
		return deepClone(input, null == inputType ? null : (TypeToken<T>)TypeToken.of(inputType), identityFilter);
	}

	/**
	 * 对输入对象进行浅克隆操作。<p>
	 * 该方法会根据输入对象的类型，调用相应的克隆包装器函数对对象进行浅克隆。<br>
	 * 具体步骤如下：<br>
	 * <li>若输入对象为 null，则直接返回 null。</li>
	 * <li>若输入类型为 null，则将输入对象的实际类作为输入类型。</li>
	 * <li>调用 {@link #cloneWrapperOf(Class)} 方法获取克隆包装器函数，并使用该函数对输入对象进行浅克隆。</li>
	 * </p>
	 * 
	 * @param <T> 输入对象的类型
	 * @param input 要进行浅克隆的输入对象
	 * @param inputType 输入对象的类型，用于指定克隆操作的目标类型
	 * @return 输入对象的浅克隆副本，如果输入对象为 null，则返回 null
	 */
	@SuppressWarnings("unchecked")
	static <T> T shallowClone(T input, Class<T> inputType) {
		if (null == input) {
			return null;
		}
		/** inputType为null或Object,对input的类型没有约束，要用input的实际类型来检查 */
		if (null == inputType || inputType == Object.class) {
			inputType = (Class<T>) input.getClass();
		}else {
			checkArgument(Primitives.wrap(inputType).isInstance(input), 
					"inputType %s is not supertype of input %s",
					inputType, input.getClass());
		}

		/** NOTE: 输入为Object对象视为不可变对象，直接返回原对象 */
		if (input.getClass() == Object.class) {
			checkArgument(inputType == Object.class, 
					"inputType must be Object.class if input is Object instance");
			return input;
		}
		if (isImmutable(inputType)) {
			/** 不可变类型不需要复制 */
			return input;
		}
		return (T) cloneWrapperOf(inputType).apply(input);
	}

	/** @see #shallowClone(Object, Class) */
	@SuppressWarnings("unchecked")
	static <T> T shallowClone(T input, Type inputType) {
		Class<?> clazz;
		if (inputType instanceof Class) {
			clazz = (Class<?>) inputType;
		} else {
			clazz = TypeToken.of(inputType).getRawType();
		}

		return (T) shallowClone(input, (Class<T>) clazz);
	}

	/**
	 * 处理包装操作过程中出现的错误。<p>
	 * 根据全局配置 {@link AoCacheGlobalConfig#throwWrapException} 的值，决定是抛出异常还是记录日志。<br>
	 * 具体处理逻辑如下：<br>
	 * <li>若 {@link AoCacheGlobalConfig#throwWrapException} 为 <code>true</code>，则抛出未检查异常，若异常为已检查异常，则将其包装为 <code>RuntimeException</code> 抛出。</li>
	 * <li>若 {@link AoCacheGlobalConfig#throwWrapException} 为 <code>false</code>，则将错误信息记录到日志中。若传入的前缀 <code>prefix</code> 为 <code>null</code>，则使用空字符串作为前缀。</li>
	 * 
	 * @param prefix 错误信息的前缀，用于标识错误来源，若为 <code>null</code> 则使用空字符串。
	 * @param e 包装操作过程中抛出的异常对象。
	 */
	private static void handleWrapError(String prefix, Throwable e) {
		if (AoCacheGlobalConfig.throwWrapException) {
			Throwables.throwIfUnchecked(e);
			throw new RuntimeException(e);
		} else {
			if (null == prefix) {
				prefix = "";
			}
			AocacheLogger.DEFAULT.log(AoCacheGlobalConfig.debugOutput,
					prefix + " failed:" + e.getClass().getSimpleName() + ":" + e.getMessage());
		}
	}

	private static abstract class AbstractWrapper<T> implements Function<T, T>{
		protected abstract T doApply(T input);
		@Override
		public final T apply(T input) {
			if(null == input){
				return null;
			}
			return doApply(input);
		}
    }
    /**
     * 克隆包装器实现类，提供类型安全的克隆操作。
     * <p>
     * 当对象实现Cloneable接口时执行深度克隆，克隆失败时返回原始对象
     * 避免未经检查的类型转换和空指针异常
     */
    private static class CloneableWrapper<T extends Cloneable> extends AbstractWrapper<T> {
		private final Method cloneMethod;
		CloneableWrapper(Method cloneMethod) {
			this.cloneMethod = checkNotNull(cloneMethod, "cloneMethod can not be null");
			cloneMethod.setAccessible(true);
		}
        @SuppressWarnings("unchecked")
		@Override
		public T doApply(T input) {
			try {
				return (T) cloneMethod.invoke(input);
			} catch (Exception e) {
				handleWrapError(CloneableWrapper.class.getSimpleName(), e);
			}
			return input;
		}
    }
	/**
     * 数组包装器实现类，提供类型安全的数组克隆操作。<p>
     * 该类继承自 AbstractWrapper，用于处理数组类型的克隆。<br>
     * 当对象为数组时，将创建一个新的数组实例，并将原数组的元素复制到新数组中。<br>
     * 克隆失败时返回原始数组，避免未经检查的类型转换和空指针异常。
     */
    private static class ArrayWrapper<T> extends AbstractWrapper<T> {
		private final TypeToken<?> elementType;
		private final IdentityFilter identityFilter;
		/**
		 * 无参构造函数，用于创建执行浅拷贝操作数组包装器实例。<p>
		 */
		ArrayWrapper() {
			this(null, IdentityFilter.IDENTITY);
		}
		/**
		 * 构造一个带有指定元素类型令牌的数组包装器实例。<p>
		 * 该构造函数会根据传入的元素类型令牌初始化包装器的元素类型，并根据元素类型是否为基本类型<br>
		 * 来决定是否进行深度克隆操作。如果元素类型令牌为 <code>null</code>，则默认不进行深度克隆。<p>
		 * 
		 * @param elementType 数组元素的类型令牌，用于指定数组元素的类型。如果为 <code>null</code>，则表示不进行深度克隆操作。
		 * @param identityFilter 用于过滤不可变类型的过滤器
		 */
		ArrayWrapper(TypeToken<?> elementType, IdentityFilter identityFilter) {
			this.elementType = elementType;
			this.identityFilter = identityFilter;
		}
		@SuppressWarnings("unchecked")
		@Override
		public T doApply(T input) {
			Class<?> componentType = null == elementType ? input.getClass().getComponentType()
					: elementType.getRawType();
			int length = Array.getLength(input);
			Object newArray = Array.newInstance(componentType, length);
			System.arraycopy(input, 0, newArray, 0, length);
			if (identityFilter != IdentityFilter.IDENTITY) {
				for (int i = 0, end_i = Array.getLength(input); i < end_i; ++i) {
					Object element = Array.get(input, i);
					Array.set(input, i, deepClone(element, (TypeToken<Object>) elementType, identityFilter));
				}
			}
			return (T) newArray;
		}
    }
    /**
     * 实例化包装器实现类，提供类型安全的实例化操作。<p>
     * 当对象有一个以自身类型为参数的构造函数时，将尝试通过该构造函数创建一个新的实例。<br>
     * 实例化失败时返回原始对象，避免未经检查的类型转换和空指针异常。
     */
    private static class CopyConstructWrapper<T> extends AbstractWrapper<T> {
    	private final Constructor<T> ctor;
		CopyConstructWrapper(Constructor<T> ctor) {
			this.ctor = ctor;
			ctor.setAccessible(true);
		}

		@Override
        public T doApply(T input) {
			try {
				return ctor.newInstance(input);
			} catch (Exception e) {
				handleWrapError(CopyConstructWrapper.class.getSimpleName(), e);
			}
			return input;
        }
    }

	private static class MapWrapper<K, V, M extends Map<K, V>> extends AbstractWrapper<M> {
		private final Constructor<M> ctor;
		MapWrapper(Constructor<M> defaultCtor) {
			this.ctor = checkNotNull(defaultCtor, "defaultCtor can not be null");
			ctor.setAccessible(true);
		} 
		@Override
		public M doApply(M input) {
			try {
				M map = (M) ctor.newInstance();
				map.putAll(input);
				return map;
			} catch (Exception e) {
				handleWrapError(MapWrapper.class.getSimpleName(), e);
			}
			return input;
		}
	}
	
	private static class CollectionWrapper<T, C extends Collection<T>> extends AbstractWrapper<C> {
		private final Constructor<C> ctor;
		CollectionWrapper(Constructor<C> defaultCtor) {
			this.ctor = checkNotNull(defaultCtor, "defaultCtor can not be null");
			ctor.setAccessible(true);
		} 
	    @Override
	    public C doApply(C input) {
			try {
				C collection = (C) ctor.newInstance();
				collection.addAll(input);
				return collection;
			} catch (Exception e) {
				handleWrapError(CollectionWrapper.class.getSimpleName(), e);
			   }
	        return input;
	    }	
	}

	/**
	 * 可序列化包装器实现类，提供类型安全的序列化克隆操作。<p>
	 * 该类继承自 AbstractWrapper，用于处理实现了 Serializable 接口的对象的克隆。<br>
	 * 当对象实现了 Serializable 接口时，将通过序列化和反序列化的方式创建一个新的对象实例。<br>
	 * 克隆失败时返回原始对象，避免未经检查的类型转换和空指针异常。
	 */
	private static class SerializableWrapper<T extends Serializable> extends AbstractWrapper<T> {
		@SuppressWarnings("unchecked")
		@Override
		public T doApply(T input) {
			try {
				ByteArrayOutputStream outputStream = new ByteArrayOutputStream(512);
				try (ObjectOutputStream out = new ObjectOutputStream(outputStream)) {
					out.writeObject(input);
				}
				byte[] objectData = outputStream.toByteArray();
				ByteArrayInputStream inputStream = new ByteArrayInputStream(objectData);
				try (ObjectInputStream in = new ObjectInputStream(inputStream)) {
					return (T) in.readObject();
				}
			} catch (Exception e) {
				handleWrapError(SerializableWrapper.class.getSimpleName(), e);
			}
			return input;
		}
	}

	private static class CreateCopyWrapper<T> extends AbstractWrapper<T> {
		private final Method createCopyMethod;
		CreateCopyWrapper(Method createCopyMethod) {
			this.createCopyMethod = createCopyMethod;
		}
		@SuppressWarnings("unchecked")
		@Override
		public T doApply(T input) {
			try {
				return (T) createCopyMethod.invoke(null, input);
			} catch (Exception e) {
				handleWrapError(CreateCopyWrapper.class.getSimpleName(), e);
			}
			return input;
		}
	}

	/**
	 * 缓冲区包装器实现类，继承自 AbstractWrapper，提供类型安全的缓冲区克隆操作。<p>
	 * 该类用于处理实现了 {@link java.nio.Buffer} 接口的对象的克隆。<br>
	 * 当对象是缓冲区类型时，会根据是否进行深度克隆的标志，选择合适的克隆方式：<br>
	 * <li>如果深度克隆标志为 <code>true</code>，则使用缓冲区类的 "allocate" 和 "put" 方法进行深度克隆。</li>
	 * <li>如果深度克隆标志为 <code>false</code>，则使用缓冲区对象的 {@link java.nio.Buffer#duplicate()} 方法进行浅克隆。</li>
	 * 
	 * @param <T> 缓冲区对象的类型，必须是实现了 {@link java.nio.Buffer} 接口的具体类。
	 */
	@SuppressWarnings("unchecked")
	private static class BufferWrapper<T extends Buffer> extends AbstractWrapper<T> {
		private final boolean deepClone;
		private final Method allocateMethod;
		private final Method putMethod;
		private final Method duplicateMethod;

	/**
	 * 构造一个缓冲区包装器实例。<p>
	 * 该构造函数用于初始化缓冲区克隆所需的信息，包括缓冲区的类类型和是否进行深度克隆的标志。<br>
	 * 根据是否进行深度克隆，会尝试解析并获取缓冲区类的 "allocate" 和 "put" 方法，用于深度克隆操作。<br>
	 * 如果深度克隆标志为 <code>false</code>，则将相关方法引用设置为 <code>null</code>。<p>
	 * 
	 * @param <T> 缓冲区对象的类型，必须是实现了 {@link java.nio.Buffer} 接口的具体类。
	 * @param clazz 缓冲区对象的类类型，用于确定缓冲区的具体实现类。
	 * @param deepClone 一个布尔值，指示是否进行深度克隆操作。<br>
	 *                  如果为 <code>true</code>，则使用 "allocate" 和 "put" 方法进行深度克隆；<br>
	 *                  如果为 <code>false</code>，则使用缓冲区对象的 {@link java.nio.Buffer#duplicate()} 方法进行浅克隆。
	 */
	BufferWrapper(Class<T> clazz, boolean deepClone) {
		this.deepClone = deepClone;
		if (deepClone) {
			try {
				allocateMethod = (Method) AocacheUtils.resolveAccessibleExecutableMember(clazz, "allocate",
						new Class<?>[] { int.class });
				putMethod = (Method) AocacheUtils.resolveAccessibleExecutableMember(clazz, "put",
						new Class<?>[] { clazz });
				duplicateMethod = null;
			} catch (NoSuchMethodException | SecurityException e) {
				throw new IllegalArgumentException("BufferWrapper:" + e.getMessage(), e);
			}
		} else {
			allocateMethod = null;
			putMethod = null;
			try {
				duplicateMethod = (Method) AocacheUtils.resolveAccessibleExecutableMember(clazz, "duplicate",
						new Class<?>[] {});
			} catch (NoSuchMethodException | SecurityException e) {
				throw new IllegalArgumentException("BufferWrapper:" + e.getMessage(), e);
			}
		}
	}

		@Override
		public T doApply(T source) {
			try {
				if (deepClone) {
					int originalPosition = source.position();
					int originalLimit = source.limit();
					/** 调用 allocate 方法 */
					T copy = (T) allocateMethod.invoke(null, source.capacity());
					source.position(0);
					source.limit(source.capacity());
					/** 调用 put 方法 */
					putMethod.invoke(copy, source);
					source.position(originalPosition);
					source.limit(originalLimit);
					copy.position(originalPosition);
					copy.limit(originalLimit);
					return copy;
				}
				return (T) duplicateMethod.invoke(source);
			} catch (IllegalAccessException | InvocationTargetException e) {
				handleWrapError(BufferWrapper.class.getSimpleName(), e);
			}
			return source;
		}
	}

	private static Member getInstantiableMember(Class<?> clazz) {
		/** 查找默认构造方法 */
		Constructor<?> ctor = defaultConstructorOf(clazz);
		if (null != ctor) {
			return ctor;
		}
		/** 查找 create 方法,例如 LinkedListMultimap */
		Method createMethod = AocacheUtils.getAccessibleMethod(clazz, "create");
		if (null != createMethod && Modifier.isStatic(createMethod.getModifiers())) {
			Class<?> returnType = createMethod.getReturnType();
			if (returnType == createMethod.getDeclaringClass()) {
				return createMethod;
			}
		}
		/** 查找 builder 方法,例如 ImmutableList */
		return getBuilderMethod(clazz, true);
	}
	/**
	 * 获取指定类的构建器方法。<p>
	 * 该方法会尝试查找类中的 "builder" 方法，并根据传入的参数决定返回 "builder" 方法还是 "build" 方法。<br>
	 * 具体查找逻辑如下：<br>
	 * <li>查找类中名为 "builder" 的公共静态方法。</li>
	 * <li>如果找到 "builder" 方法，检查其返回类型是否为静态成员类。</li>
	 * <li>在该静态成员类中查找名为 "build" 的非静态公共方法。</li>
	 * <li>如果 "build" 方法的返回类型与 "builder" 方法的声明类相同，则根据 <code>builder</code> 参数的值决定返回 "builder" 方法还是 "build" 方法。</li>
	 * 
	 * @param clazz 要查找方法的类
	 * @param builder 一个布尔值，若为 <code>true</code> 则返回 "builder" 方法，若为 <code>false</code> 则返回 "build" 方法
	 * @return 符合条件的方法，如果未找到则返回 <code>null</code>
	 */
	private static Method getBuilderMethod(Class<?> clazz, boolean builder) {
		/** 查找 builder 方法,例如 ImmutableList */
		Method builderMethod = AocacheUtils.getAccessibleMethod(clazz, "builder");
		if (null != builderMethod && Modifier.isStatic(builderMethod.getModifiers())) {
			Class<?> returnType = builderMethod.getReturnType();
			if (returnType.isMemberClass() && Modifier.isStatic(returnType.getModifiers())) {
				Method buildMethod = AocacheUtils.getAccessibleMethod(returnType, "build");
				if (null != buildMethod && !Modifier.isStatic(buildMethod.getModifiers())
						&& Modifier.isPublic(buildMethod.getModifiers())) {
					if (buildMethod.getReturnType() == builderMethod.getDeclaringClass()) {
						if (builder) {
							return builderMethod;
						}
						return buildMethod;
					}
				}
			}
		}
		return null;
	}
	/**
	 * 根据传入的可实例化成员（构造函数或方法）创建对象实例。
	 * 
	 * @param member 可实例化的成员对象，可以是构造函数或静态方法
	 * @return 新创建的对象实例
	 * @throws IllegalStateException 如果实例化过程中出现异常或无法实例化
	 */
	private static Object instantiate(Member member) {
		try {
			if (member instanceof Constructor) {
				return ((Constructor<?>) member).newInstance();
			} else if (member instanceof Method) {
				return ((Method) member).invoke(null);
			}
		} catch (IllegalAccessException | InvocationTargetException | InstantiationException
				| IllegalArgumentException e) {
			Throwables.throwIfUnchecked(e);
			throw new IllegalStateException(
					member.getName() + " is not instantiable", e);
		}
		throw new IllegalStateException(
				member.getName() + " is not instantiable");
	}

	/**
	 * 集合深度克隆包装器实现类，继承自 AbstractWrapper，提供类型安全的集合深度克隆操作。<p>
	 * 该类用于处理实现了集合接口（如 {@link java.util.Collection}）的对象的深度克隆。<br>
	 * 当对象是集合类型时，会根据集合元素的类型是否为不可变类型，选择合适的克隆方式，<br>
	 * 包括直接复制元素或对每个元素进行深度克隆。<p>
	 * 支持两种实例化方式：普通构造函数实例化和构建器（Builder）模式实例化。<p>
	 * 具体步骤如下：
	 * <li>构造函数会根据传入的可实例化类和目标类型，解析集合元素的类型，获取可实例化成员（构造函数或静态方法），并根据实例化方式获取相应的方法。</li>
	 * <li>doApply 方法会执行具体的克隆操作，包括创建新的集合实例、遍历原集合的元素，根据元素的不可变特性进行克隆，并将克隆后的元素添加到新集合中。</li>
	 * 
	 * @param <T> 集合元素的类型
	 * @param <C> 集合的类型，必须是实现了 {@link java.util.Collection} 接口的具体类
	 */
	private static class CollectionCloneWrapper<T, C extends Collection<T>> extends AbstractWrapper<C> {
		private final IdentityFilter identityFilter;
		private final Member instantiableMember;
		private final Method buildMethod;
		private final Method addMethod;
		private final Method addAllMethod;
		private final TypeToken<T> elementType;
		/**
		 * 构造一个集合深度克隆包装器实例。<p>
		 * 该构造函数用于初始化集合深度克隆所需的各种信息，包括元素类型、是否深度克隆以及可实例化成员等。<br>
		 * 具体步骤如下：<br>
		 * <li>解析传入的目标类型，获取集合元素的类型令牌。</li>
		 * <li>检查元素类型是否为不可变类型。</li>
		 * <li>获取可实例化成员（构造函数或静态方法），用于创建新的集合实例。</li>
		 * <li>如果使用构建器模式，获取相应的 add、addAll 和 build 方法。</li>
		 * 
		 * @param instantiableClass 可用于实例化集合的类，该类应提供默认构造函数或静态创建方法。
		 * @param targetType 集合的目标类型令牌，用于解析元素的类型。
		 * @param deepClone 指示是否进行深度克隆操作。
		 * @param identityFilter 用于过滤不可变类型的过滤器
		 * @throws IllegalArgumentException 如果指定的类不可实例化，或者无法找到所需的方法。
		 */
		@SuppressWarnings("unchecked")
		CollectionCloneWrapper(Class<?> instantiableClass, TypeToken<C> targetType, boolean deepClone, IdentityFilter identityFilter) {
			super();
			this.identityFilter = identityFilter;
			this.elementType = (TypeToken<T>) TypeToken.of(getTypeArguments(targetType, Collection.class)[0]);
			this.instantiableMember = getInstantiableMember(instantiableClass);
			if (this.instantiableMember == null) {
				throw new IllegalArgumentException(
						"CollectionCloneWrapper:" + instantiableClass.getName() + " is not instantiable");
			}
			if (this.instantiableMember.getName() == "builder") {
				buildMethod = getBuilderMethod(instantiableClass, false);
				try {
					addMethod = AocacheUtils.resolveAccessibleMethod(buildMethod.getReturnType(), "add",
							elementType.getRawType());
					addAllMethod = AocacheUtils.resolveAccessibleMethod(buildMethod.getReturnType(), "addAll",
							Collection.class);
				} catch (NoSuchMethodException e) {
					throw new IllegalArgumentException("CollectionCloneWrapper:" + e.getMessage(), e);
				}
			} else {
				buildMethod = null;
				addMethod = null;
				addAllMethod = null;
			}
		}
		@SuppressWarnings("unchecked")
		@Override
		public C doApply(C input) {
			Object instance = instantiate(instantiableMember);
			if (instance instanceof Collection) {
				/** 普通集合对象 */
				Collection<T> collection = (Collection<T>) instance;
				if(!input.isEmpty()){
					if(IdentityFilter.IDENTITY == identityFilter){
						collection.addAll(input); // 直接添加元素，避免了深拷贝的过程，效率高
					}else {
						for (T obj : input) {
							collection.add(deepClone(obj, elementType, identityFilter));
						}
					}
				}
				return (C) collection;
			}else {
				/** buider 模式 */
				try {
					if(!input.isEmpty()){
						if(IdentityFilter.IDENTITY == identityFilter){
							/** 调用 addAll 方法 */
							addAllMethod.invoke(instance, input);
						}else {
							for (T obj : input) {
								T element = deepClone(obj,  elementType, identityFilter);
								/** 调用 add 方法 */
								addMethod.invoke(instance, element);
							}
						}
					}
					/** 调用 build 方法 */
					return (C) buildMethod.invoke(instance);
				} catch (Exception e) {
					handleWrapError(CollectionCloneWrapper.class.getSimpleName(), e);
				}
				return input;
			}
		}
	}

	/**
	 * 映射深度克隆包装器实现类，继承自 AbstractWrapper，提供类型安全的映射深度克隆操作。<p>
	 * 该类用于处理实现了映射接口（如 {@link java.util.Map} 或 Guava 的 {@link com.google.common.collect.Multimap}）的对象的深度克隆。<br>
	 * 当对象是映射类型时，会根据键和值的类型是否为不可变类型，选择合适的克隆方式，<br>
	 * 包括直接复制键值对或对每个键和值进行深度克隆。<p>
	 * 支持两种实例化方式：普通构造函数实例化和构建器（Builder）模式实例化。<p>
	 * 具体步骤如下：
	 * <li>构造函数会根据传入的可实例化类和超类型，解析键和值的类型，获取可实例化成员（构造函数或静态方法），并根据实例化方式获取相应的方法。</li>
	 * <li>doApply 方法会执行具体的克隆操作，包括创建新的映射实例、遍历原映射的键值对，根据键和值的不可变特性进行克隆，并将克隆后的键值对添加到新映射中。</li>
	 * 
	 * @param <K> 映射键的类型
	 * @param <V> 映射值的类型
	 * @param <M> 映射的类型，可以是 {@link java.util.Map} 或 Guava 的 {@link com.google.common.collect.Multimap} 及其子类
	 */
	@SuppressWarnings({"unchecked", "rawtypes"})
	private static class MapCloneWrapper<K, V, M> extends AbstractWrapper<M> {
		private final IdentityFilter identityFilter;
		private final Member instantiableMember;
		private final Method buildMethod;
		private final Method putMethod;
		private final Method putAllMethod;
		private final TypeToken<K> keyType;
		private final TypeToken<V> valueType;

	/**
	 * 构造一个映射深度克隆包装器实例。<p>
	 * 该构造函数用于初始化映射深度克隆所需的各种信息，包括键和值的类型、可实例化成员以及相关方法。<br>
	 * 具体步骤如下：<br>
	 * <li>解析传入的超类型，获取映射的键和值的类型令牌。</li>
	 * <li>检查键和值的类型是否为不可变类型。</li>
	 * <li>获取可实例化成员（构造函数或静态方法），用于创建新的映射实例。</li>
	 * <li>根据实例化方式（普通构造或构建器模式），获取相应的 put、putAll 和 build 方法。</li>
	 * 
	 * @param instantiableClass 可用于实例化映射的类，该类应提供默认构造函数或静态创建方法。
	 * @param targetType 映射的超类型令牌，用于解析键和值的类型。
	 * @param superType 映射的超类或实现的接口，用于获取类型参数。
	 * @param identityFilter 用于过滤不可变类型的过滤器
	 * @throws IllegalArgumentException 如果指定的类不可实例化，或者无法找到所需的方法。
	 */
	MapCloneWrapper(Class<?> instantiableClass, TypeToken<M> targetType,Class<?> superType, IdentityFilter identityFilter) {
			super();
			this.identityFilter = identityFilter;
			Type[] keyValueTypes = getTypeArguments(targetType, superType);
			this.keyType = (TypeToken<K>) TypeToken.of(keyValueTypes[0]);
			this.valueType = (TypeToken<V>) TypeToken.of(keyValueTypes[1]);
			this.instantiableMember = getInstantiableMember(instantiableClass);
			if (this.instantiableMember == null) {
				throw new IllegalArgumentException(
						"MapCloneWrapper:" + instantiableClass.getName() + " is not instantiable");
			}
			if (this.instantiableMember.getName() == "builder") {
				buildMethod = getBuilderMethod(instantiableClass, false);
				try {
					putMethod = AocacheUtils.resolveAccessibleMethod(buildMethod.getReturnType(), "put",
							keyType.getRawType(), valueType.getRawType());
					putAllMethod = AocacheUtils.resolveAccessibleMethod(buildMethod.getReturnType(), "putAll",
							targetType.getRawType());
				} catch (NoSuchMethodException e) {
					throw new IllegalArgumentException("MapCloneWrapper:" + e.getMessage(), e);
				}
			} else {
				buildMethod = null;
				try {
					putMethod = AocacheUtils.resolveAccessibleMethod(instantiableClass, "put", keyType.getRawType(),
							valueType.getRawType());
					putAllMethod = AocacheUtils.resolveAccessibleMethod(instantiableClass, "putAll",
							targetType.getRawType());
				} catch (NoSuchMethodException e) {
					throw new IllegalArgumentException("MapCloneWrapper:" + e.getMessage(), e);
				}
			}
		}

		private Iterable<Map.Entry<K, V>> entires(Object input) {
			if (input instanceof Map) {
				return ((Map<K, V>) input).entrySet();
			}
			if (input instanceof Multimap) {
				return ((Multimap<K, V>) input).entries();
			} else {
				try {
					return (Iterable<Map.Entry<K, V>>) AocacheUtils.invoke(input, "entries");
				} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
						| NoSuchMethodException e) {
					Throwables.throwIfUnchecked(e);
					throw new RuntimeException(e);
				}
			}
		}

		@Override
		public M doApply(M input) {
			Object instance = instantiate(instantiableMember);
			if (instance instanceof Map) {
				/** 普通集合对象 */
				Map<K, V> map = (Map<K, V>) instance;
				if (!((Map) input).isEmpty()) {
					if (IdentityFilter.IDENTITY == identityFilter) {
						map.putAll((Map<K, V>) input);
					} else {
						for (Map.Entry<K, V> entry : entires(input)) {
							map.put(deepClone(entry.getKey(), keyType, identityFilter), deepClone(entry.getValue(), valueType, identityFilter));
						}
					}
				}
				return (M) map;
			}
			if (instance instanceof Multimap) {
				Multimap<K, V> multimap = (Multimap<K, V>) instance;
				if (!((Multimap) input).isEmpty()) {
					if (IdentityFilter.IDENTITY == identityFilter) {
						multimap.putAll((Multimap<K, V>) input);
					} else {
						for (Map.Entry<K, V> entry : entires(input)) {
							multimap.put(deepClone(entry.getKey(), keyType, identityFilter), deepClone(entry.getValue(), valueType, identityFilter));
						}
					}
				}
				return (M) multimap;
			} else {
				/** buider 模式 */
				try {
					/** 调用 isEmpty 方法 */
					boolean empty = (boolean) AocacheUtils.invoke(input, "isEmpty");
					if (!empty) {
						if (IdentityFilter.IDENTITY == identityFilter) {
							putAllMethod.invoke(instance, input);
						} else {
							for (Map.Entry<K, V> entry : entires(input)) {
								/** 调用 put 方法 */
								putMethod.invoke(instance, deepClone(entry.getKey(), keyType, identityFilter),
										deepClone(entry.getValue(), valueType, identityFilter));
							}
						}
					}
					return (M) (null == buildMethod ? instance : buildMethod.invoke(instance));
				} catch (Exception e) {
					handleWrapError(MapCloneWrapper.class.getSimpleName(), e);
				}
				return input;
			}
		}
	}

	/**
	 * JavaBean包装器实现类，继承自 AbstractWrapper，提供类型安全的 JavaBean 克隆操作。<p>
	 * 该类用于处理符合 JavaBean 规范的对象的克隆。<br>
	 * 当对象是 JavaBean 类型时，会根据是否需要深度克隆的标志，通过反射调用对象的 getter 和 setter 方法，或者直接访问字段，<br>
	 * 来创建一个新的对象实例并复制其属性值。<p>
	 * 具体步骤如下：<li>构造函数会检查传入的类是否为非空，并收集该类的所有非静态字段。</li><li>doApply 方法会执行具体的克隆操作，<br>
	 * 包括创建新的对象实例、遍历非静态字段，根据字段是否有 getter/setter 方法，选择合适的方式复制属性值。</li>
	 * 
	 * @param <T> JavaBean 的类型
	 */
	private static class JavaBeanWrapper<T> extends AbstractWrapper<T> {
		private final Class<?> clazz;
		private final IdentityFilter identityFilter;
		private final Map<String, Field> nonStaticFields;

		JavaBeanWrapper(Class<T> clazz, IdentityFilter identityFilter) {
			this.clazz = checkNotNull(clazz, "clazz is null");
			this.identityFilter = identityFilter;
			this.nonStaticFields = collectNonStaticFields(clazz);
		}

		private Object cloneField(Class<?> beanClass, Object value, Type fieldType) {
			if (null == value) {
				return null;
			}
			Type resolveType = AocacheUtils.resolveType(beanClass, fieldType);
			if (identityFilter.identity(resolveType)) {
				return value;
			} else {
				return deepClone(value, resolveType, identityFilter);
			}
		}

		@SuppressWarnings("unchecked")
		@Override
		protected T doApply(T input) {
			try {
				/** 
				 * 用于创建实例的 Class
				 * 如果input是clazz的匿名子类，则使用clazz创建实例，否则使用input的Class创建实例
				 */
				Class<?> instantiableClass = resolveSuperClassIfLocalOrAnonymous(input.getClass());
				T copy = (T) instantiableClass.getConstructor().newInstance();
				Class<?> inputClass = input.getClass();
				/** 从input中获取所有非静态字段,而不能instantiableClass获取，从这样可以避免子类的属性被忽略 */
				for (Field field : collectNonStaticFields(inputClass).values()) {
					if (Modifier.isPublic(field.getModifiers())) {
						/** 当字段为public时，直接赋值 */
						Object value = field.get(input);
						value = cloneField(inputClass, value, field.getGenericType());
						field.set(copy, value);
					} else if ((nonStaticFields.containsKey(field.getName()))
							|| (clazz != inputClass && hasReadWriteMethod(inputClass, field))) {
						/**
						 * 当input为clazz的子类时，子类可能会有增加的字段，这些字段可能是父类没有的，
						 * 所以需要判断字段是否为clazz的字段，
						 * 如果是，则需要调用getter/setter方法赋值
						 * 如果不是则判断是否有getter/setter方法，
						 * 如果有则调用getter/setter方法赋值
						 */
						String fieldName = field.getName();
						String prefix = field.getType() == boolean.class ? "is" : "get";
						String getter = prefix + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
						String setter = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
						Object value = AocacheUtils.invoke(input, getter);
						value = cloneField(inputClass, value, field.getGenericType());
						AocacheUtils.invoke(copy, setter, value);
					} else {
						/** 没有 getter/setter 方法的非public 字段直接赋值 */
						field.setAccessible(true);
						Object value = field.get(input);
						value = cloneField(inputClass, value, field.getGenericType());
						field.set(copy, value);
					}
				}
				return copy;
			} catch (Exception e) {
				handleWrapError(JavaBeanWrapper.class.getSimpleName(), e);
			}
			return input;
		}
	}

	/**
	 * 深度克隆杂项包装器实现类，继承自 AbstractWrapper，提供类型安全的深度克隆操作。<p>
	 * 该类用于处理一些特殊类型的深度克隆，这些类型无法通过常规的克隆方式进行处理。<br>
	 * 它会根据输入对象的类类型，从预定义的映射中查找匹配的函数，并使用该函数对输入对象进行处理。<br>
	 * 如果找不到匹配的函数，则直接返回输入对象。<p>
	 * 主要功能包括：<br>
	 * <li>维护一个映射，将特殊类类型映射到对应的处理函数。</li>
	 * <li>根据输入对象的类类型，查找匹配的处理函数。</li>
	 * <li>使用匹配的处理函数对输入对象进行处理，实现深度克隆。</li>
	 * 
	 * @param <T> 输入对象的类型
	 */
	@SuppressWarnings({"unchecked","rawtypes"})
	private static class DeepCloneMiscWrapper<T> extends AbstractWrapper<T> {
		private static final Map<Class<?>, Function<?, ?>> miscFuns = createMiscClassMap();
		private static final Map<Class<?>, Function<?, ?>> createMiscClassMap(){
			ImmutableMap.Builder<Class<?>, Function<?, ?>> builder = ImmutableMap.<Class<?>, Function<?,?>>builder().put(Path.class, new Function<Object, Object>() {
				@Override
				public Object apply(Object input) {
					return Paths.get(input.toString());
				}
			}).put(TypeToken.class, new Function<TypeToken, TypeToken>() {
				@Override
				public TypeToken apply(TypeToken input) {
					return TypeToken.of(input.getType());
				}
			});
			if (GUAVA_SHADED) {
				/**
				 * 当guava被shade时，反射方式实现原始TypeToken对象的克隆
				 */
				builder.put(originalClassOf(TypeToken.class), new Function<Object, Object>() {
					@Override
					public Object apply(Object input) {
						try {
							Type type = AocacheUtils.invoke(input, "getType");
							/** 调用TokenType.of静态方法 */
							return AocacheUtils.invoke(originalClassOf(TypeToken.class), "of",
									new Class<?>[] { Type.class }, null, new Object[] { type });
						} catch (Exception e) {
							handleWrapError("TypeToken Wrapper", e);
						}
						return input;
					}
				});
			}
			return builder.build();
		}
				
		@Override
		protected T doApply(T input) {
			Function fun = findMatchingFunctionForClass(input.getClass());
			if (null != fun) {
				return (T) fun.apply(input);
			}
			return input;
		}

		/**
		 * 获取与指定类匹配的处理函数。<p>
		 * 该方法会尝试从预定义的映射中查找与指定类匹配的函数。<br>
		 * 具体步骤如下：<br>
		 * <li>首先直接从映射中查找是否存在与指定类完全匹配的函数。</li>
		 * <li>如果没有找到完全匹配的函数，则遍历映射中的所有键，检查指定类是否是键类的子类或实现类。</li>
		 * <li>如果找到匹配的键类，则返回该键类对应的函数。</li>
		 * <li>如果以上都没有找到匹配的函数，则返回 <code>null</code>。</li>
		 * 
		 * @param clazz 要查找匹配函数的类
		 * @return 匹配的处理函数，如果没有找到则返回 <code>null</code>
		 */
		private static Function findMatchingFunctionForClass(Class<?> clazz) {
			Function fun = miscFuns.get(clazz);
			if (null != fun) {
				return fun;
			}
			for (Class<?> c : miscFuns.keySet()) {
				if (c.isAssignableFrom(clazz)) {
					return miscFuns.get(c);
				}
			}
			return null;

		}

		private static boolean supported(Class<?> clazz) {
			if (miscFuns.containsKey(clazz)) {
				return true;
			}
			return null != findMatchingFunctionForClass(clazz);
		}
	}
	
	/**
	 * 判定原值类型过滤器枚举类，用于定义不同的过滤规则，判断对象是否可以直接使用原值，
	 * 而无需进行额外的处理，如克隆或转换等操作。<p>
	 * 该枚举类提供了多种过滤规则，包括直接返回对象原值、判断基本数据类型、
	 * 判断不可变类型以及判断对象及其类型是否为不可变类型等。<p>
	 * 不同的枚举常量实现了不同的 {@link #identity(Type)} 方法，
	 * 以根据各自的规则对传入的对象类型进行检查。
	 */
	public static enum IdentityFilter {
		/**
		 * {@code IDENTITY} 枚举常量，用于始终返回 {@code true}，表示可以直接使用原值转换器
		 * {@link Functions#identity()}。
		 * <p>
		 * 当调用 {@link IdentityFilter#identity(Type)} 方法时，无论传入的类型是什么，都会返回
		 * {@code true}。<br>
		 * 当调用 {@link IdentityFilter#identity(TypeToken)} 方法时，无论传入的类型令牌是什么，也会返回
		 * {@code true}。
		 * <p>
		 */
		IDENTITY {
			@Override
			public boolean identity(Type type) {
				return true;
			}

			@Override
			boolean identity(TypeToken<?> token) {
				return true;
			}
		},
		/**
		 * {@code PRIMITIVE} 枚举常量，用于判断类型是否为基本数据类型。
		 * <p>
		 * 当调用 {@link IdentityFilter#identity(Type)} 方法时，<br>
		 * 若传入的类型为 {@link Class} 类型，则检查该类是否为基本数据类型；<br>
		 * 若传入的不是 {@link Class} 类型，则返回 {@code false}。
		 * <p>
		 * 当调用 {@link IdentityFilter#identity(TypeToken)} 方法时，<br>
		 * 会检查类型令牌对应的类型是否为基本数据类型。
		 * <p>
		 */
		PRIMITIVE {
			@Override
			public boolean identity(Type type) {
				if (type instanceof Class) {
					return ((Class<?>) type).isPrimitive();
				}
				return false;
			}

			@Override
			boolean identity(TypeToken<?> token) {
				return token.isPrimitive();
			}
		},
		/**
		 * {@code IMMUTABLE} 枚举常量，用于判断类型是否为简单不可变类型。
		 * <p>
		 * 当调用 {@link IdentityFilter#identity(Type)} 方法时，<br>
		 * 若传入的类型为 {@link Class} 类型，则调用 {@link DataProtections#isImmutable(Class)}
		 * 方法检查该类是否为不可变类型；<br>
		 * 若传入的不是 {@link Class} 类型，则通过 {@link TypeToken} 获取其原始类型，再调用
		 * {@link DataProtections#isImmutable(Class)} 方法检查。
		 * <p>
		 * 当调用 {@link IdentityFilter#identity(TypeToken)} 方法时，<br>
		 * 会调用 {@link DataProtections#isImmutable(Class)}
		 * 方法，传入类型令牌对应的原始类型，检查该类型是否为不可变类型。
		 * <p>
		 */
		IMMUTABLE {
			@Override
			public boolean identity(Type type) {
				if (type instanceof Class) {
					return isImmutable((Class<?>) type);
				}
				return isImmutable(TypeToken.of(type).getRawType());
			}

			@Override
			boolean identity(TypeToken<?> token) {
				return isImmutable(token.getRawType());
			}
		},
		/**
		 * {@code IMMUTABLE_ALL} 枚举常量，用于判断类型是否为完全不可变类型。
		 * <p>
		 * 与{@code IMMUTABLE}不同的是，对于容器类型，只有容器及容器元素都为不可变类型才会返回{@code true}
		 * <p>
		 * 当调用 {@link #identity(Type)} 方法时，<br>
		 * 会调用 {@link DataProtections#isImmutable(Object, Type)} 方法检查对象及其类型是否为不可变类型，<br>
		 * 若是则返回 {@code true}；否则返回 {@code false}。
		 * <p>
		 * 当调用 {@link #identity(TypeToken)} 方法时，<br>
		 * 会调用 {@link DataProtections#isImmutable(Object, TypeToken)}
		 * 方法检查对象及其类型是否为不可变类型，<br>
		 * 若是则返回 {@code true}；否则返回 {@code false}。
		 */
		IMMUTABLE_ALL {
			@Override
			public boolean identity(Type type) {
				return isImmutable(type);
			}

			@Override
			boolean identity(TypeToken<?> token) {
				return isImmutable(token);
			}
		};

		/**
		 * 抽象方法，用于根据给定的类型判断是否可以直接使用原值转换器:{@link Functions#identity()}。
		 * <p>
		 * 不同的枚举实现该方法时，会根据自身的规则对传入的对象和类型进行检查，<br>
		 * 并返回一个布尔值表示是否满足标识条件。
		 * <p>
		 * 
		 * @param type 要检查对象的类型
		 * 
		 * @return 如果满足标识条件则返回 true，否则返回 false
		 */
		public abstract boolean identity(Type type);

		/**
		 * 抽象方法，用于根据给定的类型令牌判断是否可以直接使用原值转换器:{@link Functions#identity()}。
		 * <p>
		 * 
		 * @param token 要检查对象的类型令牌
		 * 
		 * @return 如果满足标识条件则返回 true，否则返回 false
		 */
		abstract boolean identity(TypeToken<?> token);

	}
}
